The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

use strict;
{
$File::Util::Interface::Modern::VERSION = '4.130500'; # TRIAL
}
# ABSTRACT: Modern call interface to File::Util
use lib 'lib';
use File::Util::Definitions qw( :all );
use vars qw(
@ISA $AUTHORITY
@EXPORT_OK %EXPORT_TAGS
);
$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