—use
strict;
use
warnings;
package
File::Util::Interface::Modern;
{
$File::Util::Interface::Modern::VERSION
=
'4.130500'
;
# TRIAL
}
# ABSTRACT: Modern call interface to File::Util
@ISA $AUTHORITY
@EXPORT_OK %EXPORT_TAGS
)
;
use
Exporter;
$AUTHORITY
=
'cpan:TOMMY'
;
@ISA
=
qw( Exporter File::Util::Interface::Classic )
;
@EXPORT_OK
=
qw(
_remove_opts
_myargs
_names_values
_parse_in
)
;
# some of the symbols above come from File::Util::Interface::Classic but
# the _remove_opts/_names_values methods are specifically overriden in
# this package
%EXPORT_TAGS
= (
all
=> [
@EXPORT_OK
] );
# --------------------------------------------------------
# File::Util::Interface::Modern::_names_values()
# --------------------------------------------------------
sub
_names_values {
# ignore $_[0] File::Util object reference
if
(
ref
$_
[1] eq
'HASH'
) {
# method was called like $f->method( { name => val } )
return
$_
[1]
}
# ...method called like $f->methd( name => val );
goto
\
&File::Util::Interface::Classic::_names_values
;
}
# --------------------------------------------------------
# File::Util::Interface::Modern::_remove_opts()
# --------------------------------------------------------
sub
_remove_opts {
shift
;
# we don't need "$this" here
my
$args
=
shift
@_
;
return
unless
ref
$args
eq
'ARRAY'
;
my
@triage
=
@$args
;
@$args
= ();
my
$opts
= { };
while
(
@triage
) {
my
$arg
=
shift
@triage
;
# if an argument is '', 0, or undef, it's obviously not an --option ...
push
@$args
,
$arg
and
next
unless
$arg
;
# ...so give it back to the @$args
if
( UNIVERSAL::isa(
$arg
,
'HASH'
) ) {
# if we got hashref, then we were called with the new & improved syntax:
# e.g.- $ftl->method( arg => { opt => foo, opt2 => bar } );
#
# ...as oppsed to the classic syntax:
# e.g.- $ftl->method( arg => value, --opt1=value, --flag )
#
# the bit of code below makes it possible to support both call syntaxen
@$opts
{
keys
%$arg
} =
values
%$arg
;
# crane lower that rover (ahhhhh)
# err, Perl flatcopy that hashref
}
elsif
(
$arg
=~ /^--/ ) {
# got old school "--option" argument?
# it's either a bare "--option", or it's an "--option=value" pair
my
(
$opt
,
$value
) =
split
/=/,
$arg
;
# bare version
$opts
->{
$opt
} =
defined
$value
?
$value
: 1;
# ^^^^^^^ if $value is undef it's a --flag, and value=1
# sanitized version, remove leading "--" ...
my
$clean_name
=
substr
$opt
, 2;
# ...and replace non-alnum chars with "_" so the names can be
# referenced as hash keys without superfluous quoting and escaping
$clean_name
=~ s/[^[:alnum:]]/_/g;
$opts
->{
$clean_name
} =
defined
$value
?
$value
: 1;
}
else
{
# but if it's not an "--option" type arg, or a hashref of options,
# then give it back to the caller's @$args arrayref
push
@$args
,
$arg
;
}
}
return
$opts
;
}
# --------------------------------------------------------
# File::Util::Interface::Modern::_parse_in()
# --------------------------------------------------------
sub
_parse_in {
my
(
$this
,
@in
) =
@_
;
my
$opts
=
$this
->_remove_opts( \
@in
);
# always returns a hashref, given a listref
my
$in
=
$this
->_names_values(
@in
);
# always returns a hashref, given anything
# merge two hashrefs
@$in
{
keys
%$opts
} =
values
%$opts
;
return
$in
;
}
# --------------------------------------------------------
# File::Util::Interface::Modern::DESTROY()
# --------------------------------------------------------
sub
DESTROY { }
1;
__END__
=pod
=head1 NAME
File::Util::Interface::Modern - Modern call interface to File::Util
=head1 VERSION
version 4.130500
=head1 DESCRIPTION
Provides a ::Modern-style interface for argument passing to and between the
public and private methods of File::Util.
Whereas call syntax used to only work like this:
some_method( main_arg => value, qw/ --opt=value --patern=^foo --flag / )
This module allows File::Util to work with calls that are more consistent
with current practices in Perl, like this:
some_method( main_arg => { arg => value, opt => value, flag => 1 } );
-or-
some_method( '/var/log' => { match => [ qr/.*\.log/, qr/access|error/ ] } )
Users, don't use this module by itself. It is intended for internal use only.
=cut