Ancient
view release on metacpan or search on metacpan
lib/util.pm view on Meta::CPAN
package
util;
use strict;
use warnings;
our $VERSION = '0.18';
require XSLoader;
XSLoader::load('util', $VERSION);
1;
__END__
=head1 NAME
util - Functional programming utilities with XS acceleration
=head1 SYNOPSIS
use util qw(
memo pipeline compose partial lazy force dig tap clamp identity always
noop stub_true stub_false stub_array stub_hash stub_string stub_zero
nvl coalesce first any all none
first_gt first_lt first_ge first_le first_eq first_ne
final final_gt final_lt final_ge final_le final_eq final_ne
any_gt any_lt any_ge any_le any_eq any_ne
all_gt all_lt all_ge all_le all_eq all_ne
none_gt none_lt none_ge none_le none_eq none_ne
uniq partition pick omit pluck defaults count replace_all negate once
is_ref is_array is_hash is_code is_defined is_string
is_empty starts_with ends_with trim ltrim rtrim
is_true is_false bool
is_num is_int is_blessed is_scalar_ref is_regex is_glob
is_positive is_negative is_zero
is_even is_odd is_between
is_empty_array is_empty_hash array_len hash_size
array_first array_last
maybe sign min2 max2
);
# Type predicates - compile-time optimized
if (is_array($data)) { ... }
if (is_hash($config)) { ... }
if (is_code($callback)) { ... }
if (is_defined($value)) { ... }
# Boolean/Truthiness predicates
if (is_true($value)) { ... } # Perl truth semantics
if (is_false($value)) { ... } # Perl false semantics
my $normalized = bool($value); # Normalize to 1 or ''
# Extended type predicates
if (is_num($value)) { ... } # Numeric value or looks like number
if (is_int($value)) { ... } # Integer value
if (is_blessed($obj)) { ... } # Blessed reference
if (is_scalar_ref($ref)) { ... } # Scalar reference
if (is_regex($qr)) { ... } # Compiled regex (qr//)
if (is_glob(*FH)) { ... } # Glob
# Numeric predicates
if (is_positive($num)) { ... } # > 0
if (is_negative($num)) { ... } # < 0
if (is_zero($num)) { ... } # == 0
if (is_even($num)) { ... } # n & 1 == 0
if (is_odd($num)) { ... } # n & 1 == 1
if (is_between($n, 1, 10)) { ... } # Range check (inclusive)
# Collection predicates - direct AvFILL/HvKEYS access
if (is_empty_array($aref)) { ... }
if (is_empty_hash($href)) { ... }
my $len = array_len($aref); # Direct AvFILL access
my $size = hash_size($href); # Direct HvKEYS access
my $first = array_first($aref); # Without slice overhead
my $last = array_last($aref); # Without slice overhead
# String predicates - direct SvPV/SvCUR access
if (is_empty($str)) { ... }
if (starts_with($filename, '/')) { ... }
if (ends_with($filename, '.txt')) { ... }
# Memoization - cache function results
my $fib = memo(sub {
my $n = shift;
return $n if $n < 2;
return $fib->($n-1) + $fib->($n-2);
});
# Pipelines - chain transformations
my $result = pipeline($data,
\&fetch,
\&transform,
\&process
);
# Lazy evaluation - defer computation
my $expensive = lazy { heavy_computation() };
my $result = force($expensive);
# Safe navigation - no exceptions
my $val = dig($hash, qw(deep nested key));
# Null coalescing
my $val = nvl($maybe_undef, $default);
my $val = coalesce($a, $b, $c); # First defined
# List operations with callbacks
my $found = first(sub { $_->{active} }, \@users);
if (any(sub { $_ > 10 }, \@numbers)) { ... }
if (all(sub { $_->{valid} }, \@records)) { ... }
# Specialized predicates - pure C, no callback overhead
my $large = first_gt(\@numbers, 100); # first > 100
my $adult = first_ge(\@users, 'age', 18); # first user age >= 18
lib/util.pm view on Meta::CPAN
=head1 NUMERIC OPS
These functions use custom ops for numeric operations.
=head2 sign
my $s = sign($number);
Returns -1 if C<$number> is negative, 0 if zero, 1 if positive.
Returns undef for non-numeric values.
B<Note:> If you only need the comparison result and don't need undef handling,
the spaceship operator C<< $number <=> 0 >> is faster.
=head2 min2
my $smaller = min2($a, $b);
Returns the smaller of two numeric values.
=head2 max2
my $larger = max2($a, $b);
Returns the larger of two numeric values.
=head1 BOOLEAN/TRUTHINESS PREDICATES
These functions use custom ops for Perl truth semantics checks.
=head2 is_true
my $bool = is_true($value);
Returns true if C<$value> is truthy according to Perl semantics.
This means: defined, non-empty string, non-zero number.
=head2 is_false
my $bool = is_false($value);
Returns true if C<$value> is falsy according to Perl semantics.
This includes: undef, empty string "", string "0", numeric 0.
=head2 bool
my $normalized = bool($value);
Normalizes C<$value> to a boolean (1 for true, '' for false).
Useful when you need a consistent boolean representation.
=head1 EXTENDED TYPE PREDICATES
These functions use custom ops for extended type checking.
=head2 is_num
my $bool = is_num($value);
Returns true if C<$value> is numeric (has a numeric value or
looks like a number). Uses C<looks_like_number> for strings.
=head2 is_int
my $bool = is_int($value);
Returns true if C<$value> is an integer. Returns true for
whole number floats like 5.0.
=head2 is_blessed
my $bool = is_blessed($value);
Returns true if C<$value> is a blessed reference (an object).
Uses C<sv_isobject>.
=head2 is_scalar_ref
my $bool = is_scalar_ref($value);
Returns true if C<$value> is a scalar reference (not array/hash/code).
=head2 is_regex
my $bool = is_regex($value);
Returns true if C<$value> is a compiled regular expression (qr//).
=head2 is_glob
my $bool = is_glob($value);
Returns true if C<$value> is a glob (like *STDIN, *main::foo).
=head1 NUMERIC PREDICATES
These functions use custom ops for numeric comparisons.
They first check if the value is numeric, then perform the comparison.
=head2 is_positive
my $bool = is_positive($value);
Returns true if C<$value> is numeric and greater than zero.
Returns false for non-numeric values.
=head2 is_negative
my $bool = is_negative($value);
Returns true if C<$value> is numeric and less than zero.
Returns false for non-numeric values.
=head2 is_zero
my $bool = is_zero($value);
Returns true if C<$value> is numeric and equals zero.
Returns false for non-numeric values.
=head2 is_even
( run in 1.917 second using v1.01-cache-2.11-cpan-39bf76dae61 )