=head1 NAME

Perl::Util - Perl Extensions


=head1 SYNOPSIS


  use Perl::Util qw(grep_first);
  grep_first {$_ eq 'b'} qw(a b b c);



=head1 EXPORTS

Nothing exported by default

=over

=item Exported upon request

ONE_KB, ONE_MB, ONE_GB, ONE_TB, ONE_PB, ONE_EB, ONE_ZB, ONE_YB, EXPR_NUMERIC, warnf, is_numeric, int_div, str_ref, grep_first, grep_first_index, push_uniq, unshift_uniq, index_unescaped, index_match, index_imatch, checksum, bytesize, reftype, isa, can, strftime, strptime


=item :const

ONE_KB, ONE_MB, ONE_GB, ONE_TB, ONE_PB, ONE_EB, ONE_ZB, ONE_YB, EXPR_NUMERIC

=item :std

warnf, is_numeric, int_div, str_ref, grep_first, grep_first_index, push_uniq, unshift_uniq, index_unescaped, index_match, index_imatch, checksum, bytesize, reftype, isa, can, strftime, strptime

=item :all

ONE_KB, ONE_MB, ONE_GB, ONE_TB, ONE_PB, ONE_EB, ONE_ZB, ONE_YB, EXPR_NUMERIC, warnf, is_numeric, int_div, str_ref, grep_first, grep_first_index, push_uniq, unshift_uniq, index_unescaped, index_match, index_imatch, checksum, bytesize, reftype, isa, can, strftime, strptime


=back

=head1 DEPENDENCIES

This module requires these other modules and libraries:

    DateTime
    Error::Simple
    Scalar::Util
    Compress::Zlib
    Error::Logical
    Error::Programatic
    Perl::Options
    Time::Piece
    constant
    Exporter
    Carp
    DateTime::TimeZone
    Time::Regex::Strptime
    MIME::Base64
    Time::Regex
    Time::Regex::Strftime

=head1 DESCRIPTION




=head1 EXAMPLES

This example will B<not> abort:

  # Load this module
  use Perl::Util qw(:all);




=head1 PUBLIC INTERFACE

=head2 :const

=over

=item Byte size constants




  ONE_KB # kilo/kibi
  ONE_MB # mega/mebi
  ONE_GB # giga/gibi
  ONE_TB # tera/tebi
  ONE_PB # peta/pebi
  ONE_EB # exa/exbi
  ONE_ZB # zetta/zebi
  ONE_YB # yotta/yobi

See also: L</bytesize>, L<http://en.wikipedia.org/wiki/Byte>



=back


=head2 str_ref

=over

=item Create a scalar reference





This example:


  my $a = str_ref("a"); $$a;



I<will return>:

  a



=back


=head2 warnf

=over

=item Akin to printf



See also: C<sprintf>



=back


=head2 is_numeric

=over

=item Is the given string a numeric



We use a (slower) regular expression technique because performing an eval 
introduces inconspicuous security considerations.


This example will return true:


  is_numeric('-1');



This example will return true:


  is_numeric('0');



This example will return true:


  is_numeric('+1');



This example will return true:


  is_numeric('3.14');



This example will return true:


  is_numeric('6.02214E23');



This example will return true:


  is_numeric('6.626068e-34');



This example will return false:


  is_numeric('3.1.4');



This example will return false:


  is_numeric('');



This example will return false:


  is_numeric('three');



This example will return false:


  is_numeric(undef);




=back


=head2 int_div

=over

=item Integer division



Returns an array with the number of times the divisor is contained in the
dividend, and the remainder.


This example:

  # 3 divided by 2
  join('r',int_div(3,2));



I<will return>:

  1r1


This example:

  # 3.9 divided by 2 (does not round)
  join('r',int_div(3.9,2));



I<will return>:

  1r1


This example will abort:

  # divide by zero
  int_div(3,0);



This example will abort:

  # not numeric
  int_div('three',1);




=back


=head2 grep_first

=over

=item Like grep, but stop processing after the first true value





This example:

  # first item with an \'a\' in it
  grep_first {/a/} qw(apple banana cherry);



I<will return>:

  apple



=back


=head2 grep_first_index

=over

=item Like grep_first, but return the index





This example:

  # index of first item with an \'a\' in it
  grep_first_index {/a/} qw(apple banana cherry);



I<will return>:

  0



=back


=head2 push_uniq

=over

=item Push a value (or values) unless they exist






=back


=head2 unshift_uniq

=over

=item Unshift a value (or values) unless they exist






=back


=head2 index_unescaped

=over

=item Locate unescaped character in string



See also: C<index>



=back


=head2 index_match

=over

=item Index of expression within a string




Index is -1 I<One less than the base C<$[>> when C<$expression> is not found.

In array context, C<($index, $match)> is returned, where:


  $index        Index of expression
  $match        Matched substring


This example:


  index_match("abracadabra", "[cd]")



I<will return>:

  4


This example:


  index_match("abracadabra", "a", 3)



I<will return>:

  3


This example:


  index_match("abracadabra", "d{2,2}")



I<will return>:

  -1


This example:


  my ($p, $str) = index_match("scant", "can");
  $p + length($str);



I<will return>:

  4


This example:


  index_match("foobar foo bar", '\bfoo\b') # zero-width test



I<will return>:

  7


This example:


  index_match("foobar foo bar", 'Bar') # no-match



I<will return>:

  -1


This example:


  index_match("aa", "a")



I<will return>:

  0


This example:


  index_match("aa", "a", 1)



I<will return>:

  1



=back


=head2 index_imatch

=over

=item Index of expression within a string (case insensitive)



See L</index_match>


This example:


  index_imatch("foobar foo bar", 'Bar') # Case insensitive match



I<will return>:

  3


This example:


  index_imatch(" b\n a", '\s*a') # Case insensitive match



I<will return>:

  2



=back


=head2 checksum

=over

=item Compute a checksum



Parameters are utf8 encoded to avoid wide character issues.


This example:


  checksum('“Hello”', 'world');



I<will return>:

  1625030915



=back


=head2 bytesize

=over

=item Convert bytes to human-readable byte size




options:


  -precision => 3     Use Three decimal places.
  -binary_symbol      Use binary symbol (KiB instead of KB)


This example:


  bytesize(10)



I<will return>:

  10 B


This example:


  bytesize(11028)



I<will return>:

  10.77 KB


This example:


  bytesize(1000 ** 3, -precision => 4)



I<will return>:

  953.6743 MB


This example:


  bytesize(2 ** 30)



I<will return>:

  1 GB


This example:


  bytesize(2 ** 59, -binary_symbol)



I<will return>:

  512 PiB



=back


=head2 reftype

=over

=item Extends Scalar::Util::reftype




We differentiate between C<undef> and scalar input by only returning C<undef>
when the unknown is undefined.


This example will B<not> return a defined value:


  reftype(undef)



This example:


  reftype('')



I<will return>:

  


This example:


  reftype({})



I<will return>:

  HASH


This example:


  reftype([])



I<will return>:

  ARRAY


This example:


  my $a = ''; reftype(\$a)



I<will return>:

  SCALAR


This example:


  my $a = ''; my $b = \$a; reftype(\$b)



I<will return>:

  REF



=back


=head2 isa

=over

=item Static method which provides UNIVERSAL->isa functionality





This example will return true:


  isa({}, 'HASH')



This example will return true:


  isa([], 'ARRAY')




=back


=head2 can

=over

=item Static method which provides UNIVERSAL->can functionality






=back


=head2 %Time_Formats

=over

=item Alias and values in strftime format.




These values will be used by Time::Piece to both parse (strptime) and format
(strftime) a given time.



=back


=head1 PACKAGE INTERNALS

=head2 _index_match

=over

=item Common implementation for L</index_match> and L</index_imatch>



where:

  $str, \$str   Search string
  $re           Substring expression
  $pos          Start position (use undef, not zero unless you mean it)
  $ic           Ignore case (boolean)



=back



=head1 AUTHORS

    Ryan Gies <ryangies@cpan.org>

=head1 COPYRIGHT

    Copyright (C) 2014-2016 by Ryan Gies. All rights reserved.
    Copyright (C) 2006-2013 by Livesite Networks, LLC. All rights reserved.
    Copyright (C) 2000-2005 by Ryan Gies. All rights reserved.
    Redistribution and use in source and binary forms, with or without 
    modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright notice, 
    this list of conditions and the following disclaimer.
    * The origin of this software must not be misrepresented; you must not 
    claim that you wrote the original software. If you use this software in a 
    product, an acknowledgment in the product documentation would be 
    appreciated but is not required.
    * Altered source versions must be plainly marked as such, and must not be 
    misrepresented as being the original software.
    * The name of the author may not be used to endorse or promote products 
    derived from this software without specific prior written permission.

    THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED 
    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
    EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
    OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
    OF SUCH DAMAGE.
    To the best of our knowledge, no patented algorithms have been used. However, we
    do not have the resources to carry out a patent search, and therefore cannot 
    give any guarantee of the above statement.

=cut

