# --8<--8<--8<--8<--
#
# Copyright (C) 2007 Smithsonian Astrophysical Observatory
#
# This file is part of String::Interpolate::RE
#
# String::Interpolate::RE is free software: you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# -->8-->8-->8-->8--
package String::Interpolate::RE;
use strict;
use warnings;
use Carp;
use base 'Exporter';
our @EXPORT_OK = qw( strinterp );
our $VERSION = '0.03';
sub strinterp
{
my ( $text, $var, $opts ) = @_;
$var = {} unless defined $var;
## no critic (ProhibitAccessOfPrivateData)
my %opt = ( raiseundef => 0,
emptyundef => 0,
useenv => 1,
format => 0,
defined $opts
? ( map { (lc $_ => $opts->{$_ }) } keys %{$opts} )
: (),
);
## use critic
my $fmt = $opt{format} ? ':([^}]+)' : '()';
$text =~ s{
\$ # find a literal dollar sign
( # followed by either
{(\w+)(?:$fmt)?} # a variable name in curly brackets ($2)
# and an optional sprintf format
| # or
(\w+) # a bareword ($3)
)
}{
my $t = defined $4 ? $4 : $2;
my $v =
# in user provided variable hash?
defined $var->{$t} ? $var->{$t}
# maybe in the environment
: $opt{useenv} && exists $ENV{$t} ? $ENV{$t}
# undefined: throw an error?
: $opt{raiseundef} ? croak( "undefined variable: $t\n" )
# undefined: replace with ''?
: $opt{emptyundef} ? ''
# undefined
: undef
;
# if not defined, just put it back into the string
! defined $v ? '$' . $1
# no format? return as is
: ! defined $3 || $3 eq '' ? $v
# format it
: sprintf( $3, $v)
;
}egx;
return $text;
}
1;
__END__
=head1 NAME
String::Interpolate::RE - interpolate variables into strings
=head1 SYNOPSIS
use String::Interpolate::RE qw( interpolate );
$str = strinterp( "${Var1} $Var2", \%vars, \%opts );
=head1 DESCRIPTION
This module interpolates variables into strings, using the passed
C<%vars> hash as well as C<%ENV> as the source of the values.
It uses regular expression matching rather than Perl's built-in
interpolation mechanism and thus hopefully does not suffer from the
security problems inherent in using B to interpolate into
strings of suspect ancestry.
=head1 INTERFACE
=over
=item strinterp
$str = strinterp( $template );
$str = strinterp( $template, \%var );
$str = strinterp( $template, \%var, \%opts );
Interpolate variables into a template string, returning the
resultant string. The template string is scanned for tokens of the
form
$VAR
${VAR}
where C is composed of one or more word characters (as defined by
the C<\w> Perl regular expression pattern). If a matching token is a
key in either the optional C<%var> hash or in the C<%ENV>
hash the corresponding value will be interpolated into the string at
that point. REs which are not defined are by default left as is
in the string.
The C<%opts> parameter may be used to modify the behavior of this
function. The following (case insensitive) keys are recognized:
=over
=item Format
If this flag is true, the template string may provide a C
compatible format which will be used to generate the interpolated
value. The format should be appended to the variable name with
an intervening C<:> character, e.g.
${VAR:fmt}
For example,
%var = ( foo => 3 );
print strinterp( '${foo:%03d}', \%var, { Format => 1 } );
would result in
003
=item RaiseUndef
If true, a variable which has not been defined will result in an
exception being raised. This defaults to false.
=item EmptyUndef
If true, a variable which has not been defined will be replaced with
the empty string. This defaults to false.
=item UseENV
If true, the C<%ENV> hash will be searched for variables which are not
defined in the passed C<%var> hash. This defaults to true.
=back
=back
=head1 DIAGNOSTICS
=over
=item C<< undefined variable: %s >>
This string is thrown if the C option is set and the
variable C<%s> is not defined.
=back
=head1 BUGS AND LIMITATIONS
No bugs have been reported.
Please report any bugs or feature requests to
C, or through the web interface at
L.
=head1 SEE ALSO
Other CPAN Modules which interpolate into strings are
L and L. This module avoids the use
of B and presents a simpler interface.
=head1 VERSION
Version 0.01
=head1 LICENSE AND COPYRIGHT
Copyright (c) 2007 The Smithsonian Astrophysical Observatory
String::Interpolate::RE is free software: you can redistribute
it and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
=head1 AUTHOR
Diab Jerius Edjerius@cpan.orgE