Banal-Mini-Utils
view release on metacpan or search on metacpan
lib/Banal/Mini/Utils.pm view on Meta::CPAN
polyvalent
hash_access
hash_lookup
hash_lookup_staged
inverse_dict
inverse_mapping
maybe
maybe_kv
peek
tidy_arrayify
first_viable
invoke_first_existing_method
affixed
prefixed
suffixed
sanitize_env_var_name
sanitize_subroutine_name
sanitize_identifier_name
);
# Add function aliases with underscore prefixes (single & double)
my @ok = @EXPORT_OK;
foreach my $pfx ('_', '__') {
{ no strict 'refs';
*{ __PACKAGE__ . '::' . $pfx . $_ } = \&{ __PACKAGE__ . '::' . $_ } for @ok ;
}
push @EXPORT_OK, ( map {; $pfx . $_ } (@ok) );
}
}
#say STDERR 'EXPORT_OK : ' . np @EXPORT_OK;
#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
# UTILITY FUNCTIONS
#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
#----------------------------------------------------------
# CLASS / OBJECT related functions
#----------------------------------------------------------
#######################################
sub polyvalent { # Helps with the parameter processing of polyvalent (object or class) methods
#######################################
my $proto = shift;
my $self = blessed $proto ? $proto : $proto->new();
my $class = blessed $self;
wantarray ? ($self, $class, $proto) : $self;
}
#######################################
sub msg(@) { # Message text builder to be used in error output (warn, die, ...)
#######################################
my $o = blessed ($_[0]) ? shift : caller();
state $pfx = eval { $o->_msg_pfx(@_) } // '';
join ('', $pfx, @_, "\n")
}
#..........................................................
# STRING/TEXT processing functions
#..........................................................
sub prefixed ($@) {
my %opts = %{ ref ($_[0]) eq 'HASH' ? shift : +{ prefix => shift} };
affixed(\%opts, @_ )
}
sub suffixed ($@) {
my %opts = %{ ref ($_[0]) eq 'HASH' ? shift : +{ suffix => shift} };
affixed(\%opts, @_ )
}
sub affixed ($@) {
my %opts = %{ ref ($_[0]) eq 'HASH' ? shift : +{} };
my $pfx = exists $opts{prefix} ? ( $opts{prefix} // '') : '';
my $sfx = exists $opts{suffix} ? ( $opts{suffix} // '') : '';
map {; $pfx . $_ . $sfx } @_
}
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
sub sanitize_env_var_name (;$) { &sanitize_identifier_name }
sub sanitize_subroutine_name (;$) { &sanitize_identifier_name }
sub sanitize_identifier_name (;$) {
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
# cleanse (sanitize) the name by replacing non-alphanumeric chars with underscores.
my $name = (@_) ? shift : $_; # If no argument is given, use the default SCALAR variable as our argument.
$name =~ s/[^_A-Za-z0-9]/_/g;
return $name;
}
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# HASH related functions
#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
sub peek {
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
my ($h, $keys) = @_;
my @keys = tidy_arrayify($keys);
my $v;
foreach my $key (@keys) {
$v = exists $h->{$key} ? $h->{$key} : undef;
return $v if defined($v);
}
# Allow falling back to a set of defaults
# In scalar context, the first one defined wins.
# In list context, we return a list that contains all of the defined results
wantarray ? ( grep { defined } @_ ) : first { defined } @_;
}
lib/Banal/Mini/Utils.pm view on Meta::CPAN
return $res;
}
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
# ARRAY & LIST related functions
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
######################################
sub tidy_arrayify(;@) { local $_; my @res = ( grep { defined $_ } ( uniq( arrayify( @_) ))) }
#######################################
#=begin STOLEN_FROM_List_MoreUtils
# ------------------------------------------------------
# TAU: The two routines, as well as the comment about 'leaks' were stolen from C<List::MoreUtils>
# The only thing I did was privatizing names and turning 'flatten' into a proper subroutine (instead of a scalar CODE closure)
# That allowed me to get rid of a warning.
# ------------------------------------------------------
# "leaks" when lexically hidden in arrayify.
# sub flatten { map { (ref $_ and ("ARRAY" eq ref $_ or overload::Method($_, '@{}'))) ? (flatten(@{$_})) : ($_) } @_; }
# sub arrayify { map { flatten($_) } @_; }
# #=cut
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
sub first_viable (&@) {
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
my $f = shift; # CODE BLOCK or subroutine ref. A closure is OK, too.
my @e = ();
local $_;
#local $@; # so that we don't mess up caller's eval/error handling.
eval { 1 }; # resets $@ to whatever perl considers to be 'success';
# This part, as well as the general flow, is copied shamelessly from the 'first()' function in C<List::Util::PP>.
unless ( length ref $f && eval { $f = \&$f; 1 } ) {
require Carp;
Carp::croak("Not a subroutine reference");
}
# Return the result of the first viable evaluation (i.e. first one that doesn't die on us, for whatever reason )
foreach ( @_) {
my ($item) = ($_);
if (wantarray) { my @v = ( eval { $f->() } ); return @v unless $@; }
else { my $v = eval { $f->() } ; return $v unless $@; }
# No luck. Save the error, for an eventual error stack output if we die.
push @e, {
item => $item, err => $@,
msg=> "Failed to invoke CODE BLOCK on item '$item', with the error : '$@'\n",
};
}
# NO LUCK with any invocation.
# At this point, '$@' would normally be set to a true value by the last failed eval.
if (@e) {
my @emsg = map { $_->{msg} } @e;
my $name = (caller(0))[3]; # The name of this particular subroutine.
croak "$name : Failed to sucessfully invoke any of the given code blocks!\n"
. "Here's the list of all errors:\n\n @emsg"
}
return;
}
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
sub invoke_first_existing_method {
#&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
my $o = shift;
my @methods = arrayify(@_);
my @args = ();
first_viable { $o->$_(@args) } @methods;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Banal::Mini::Utils - Provide several MUNGER functions that may be use in conjunction with C<MooseX::MungeHas>.
=head1 VERSION
version 0.002
=head1 SUPPORT
Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Banal-Mini-Utils>
(or L<bug-Banal-Mini-Utils@rt.cpan.org|mailto:bug-Banal-Mini-Utils@rt.cpan.org>).
I am also usually active on irc, as 'ether' at C<irc.perl.org>.
=head1 AUTHOR
Tabulo <tabulo@cpan.org>
=head1 CONTRIBUTOR
=for stopwords Ayhan
Ayhan <dev@tabulo.net>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2018 by Tabulo.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
( run in 2.086 seconds using v1.01-cache-2.11-cpan-5735350b133 )