Scalar-In/lib/Scalar/In.pm
package Scalar::In; ## no critic (TidyCode)
use strict;
use warnings;
use Sub::Exporter -setup => {
exports => [ qw( string_in numeric_in ) ],
groups => {
default => [ qw( string_in ) ],
},
};
our $VERSION = '0.002';
# using dualvars
my $true = ! 0;
my $false = ! 1;
sub string_in (++) { ## no critic (SubroutinePrototypes)
my ( $any1, $any2 ) = @_;
my $ref_any1 = ref $any1;
my @any1
= $ref_any1 eq 'ARRAY'
? @{$any1}
: $ref_any1 eq 'HASH'
? keys %{$any1}
: $any1;
for my $string ( @any1 ) {
if ( defined $string ) {
$string .= q{}; # stingify object
}
my $ref_any2 = ref $any2;
my @any2
= $ref_any2 eq 'ARRAY'
? @{$any2}
: $ref_any2 eq 'HASH'
? keys %{$any2}
: $any2;
ITEM:
for my $item ( @any2 ) {
if ( ! defined $string || ! defined $item ) {
return ! ( defined $string xor defined $item );
}
if ( ref $item eq 'Regexp' ) {
$string =~ $item
and return $true;
next ITEM;
}
ref $item eq 'CODE'
and return $item->($string);
$string eq q{} . $item # stingify object
and return $true;
}
}
return $false;
}
sub numeric_in (++) { ## no critic (SubroutinePrototypes)
my ( $any1, $any2 ) = @_;
my $ref_any1 = ref $any1;
my @any1
= $ref_any1 eq 'ARRAY'
? @{$any1}
: $ref_any1 eq 'HASH'
? keys %{$any1}
: $any1;
for my $numeric ( @any1 ) {
if ( defined $numeric ) {
$numeric += 0; # numify object
}
my $ref_any2 = ref $any2;
my @any2
= $ref_any2 eq 'ARRAY'
? @{$any2}
: $ref_any2 eq 'HASH'
? keys %{$any2}
: $any2;
ITEM:
for my $item ( @any2 ) {
if ( ! defined $numeric || ! defined $item ) {
return ! ( defined $numeric xor defined $item );
}
if ( ref $item eq 'Regexp' ) {
$numeric =~ $item
and return $true;
next ITEM;
}
ref $item eq 'CODE'
and return $item->($numeric);
$numeric == ( 0 + $item ) # numify object
and return $true;
}
}
return $false;
}
# $Id$
1;
__END__
=head1 NAME
Scalar::In - replacement for smartmatch
=head1 VERSION
0.002
=head1 SYNOPSIS
use Scalar::In; # imports string_in
use Scalar::In 'numeric_in'; # imports numeric_in
use Scalar::In string_in => { -as => 'in' }; # imports in
use Scalar::In numeric_in => { -as => 'num_in' }; # imports num_in
=head1 EXAMPLE
Inside of this Distribution is a directory named example.
Run this *.pl files.
=head1 DESCRIPTION
This module was written because the smartmatch operator C<~~>
was deprecated as experimental.
That module implements some "in" subroutines
with smartmatch similar behaviour.
First I tried to delete the obsolete looking C<numeric_in>.
In tests I realized
that objects with overloaded C<+> working there
but C<string_in> expects objects with overloaded C<"">.
So there are some special cases for C<numeric_in>.
Because of such minimal cases C<numeric_in> is not exported as default.
=head1 SUBROUTINES/METHODS
=head2 subroutine string_in
"any1" or "any2" can contain 0 or more values.
The first string match of "any1" and "any2" will return true.
Also the frist match of undef in "any1" and "any2" will return true.
All other will return false.
In case of a hash or hash reference the keys are used.
$boolean = string_in( [$@%]any1, [$@%]any2 );
Allowed values for $any1:
undef, $string, $numeric, $object, $array_ref, $hash_ref
Allowed values for @any1 or if $any1 is an array reference:
$string, $numeric, $object
Allowed values for $any2:
undef, $string, $numeric, $object, $array_ref, $hash_ref, $regex, $code_ref
Allowed values for @any2 or if $any2 is an array reference:
$string, $numeric, $object, $regex, $code_ref
All given values will be used as string if they are defined.
=head3 some examples
true if $string is undef
$boolean = string_in( $string, undef );
true if $string is eq 'string'
$boolean = string_in( $string, 'string' );
true if $string contains abc or def
$boolean = string_in( $string, qr{ abc | def }xms );
true if $string begins with abc
$boolean = string_in(
$string,
sub {
my $str = shift;
return 0 == index $str, 'abc';
},
);
true if $object overloads C<""> and that is C<eq> 'string'.
Objects in the 2nd parameter should also overload C<"">.
$boolean = string_in( $object, 'string' );
true if any key in the hash or hash reference will match
$boolean = string_in( $string, $hash_ref );
$boolean = string_in( $string, %hash );
=head2 subroutine numeric_in
A given value will be used as numeric if it is defined.
Maybe that thows a numeric warning if a string looks not like numeric.
The difference to subroutine string_in is,
that here is operator C<==> used instead of operator C<eq>.
$boolean = numeric_in( $numeric, undef );
$boolean = numeric_in( $numeric, 123 );
$boolean = numeric_in( $numeric, qr{ 123 | 456 }xms );
$boolean = numeric_in( $numeric, $array_ref );
$boolean = numeric_in( $numeric, @array );
$boolean = numeric_in( $numeric, $hash_ref );
$boolean = numeric_in( $numeric, %hash );
true if $numeric > 1
$boolean = numeric_in(
$numeric,
sub {
my $num = shift;
return $num > 1;
},
);
true if $object overloads C<+> and that is C<==> 123.
$boolean = numeric_in( $object, 123 );
Objects that overload C<+> also allowed as 2nd parameter
or in a array or array reference.
=head1 DIAGNOSTICS
none
=head1 CONFIGURATION AND ENVIRONMENT
nothing
=head1 DEPENDENCIES
L<Sub::Exporter|Sub::Exporter>
=head1 INCOMPATIBILITIES
nothing
=head1 BUGS AND LIMITATIONS
nothing
=head1 SEE ALSO
smartmatch operator ~~
=head1 AUTHOR
Steffen Winkler
=head1 LICENSE AND COPYRIGHT
Copyright (c) 2013,
Steffen Winkler
C<< <steffenw at cpan.org> >>.
All rights reserved.
This module is free software;
you can redistribute it and/or modify it
under the same terms as Perl itself.