String-Expand

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

  $expanded = expand_string( $str, \%vars )
    This function expands embedded variable references in the passed string,
    and returns the expanded copy.

    $str    A string possibly containing variable expansions

    \%vars  Reference to a hash containing variable values

    Returns A string with variables expanded

  expand_strings( \%strs, \%overlay )
    This function takes a hash of strings, and expands variable names
    embedded in any of them, in the same form as the string passed to
    "expand_string()". Expansions may refer to other strings, or to values
    in the "*%overlay*" hash. Values in the main variables hash take
    precidence over values in the overlay.

    Where values refer to other values, care must be taken to avoid cycles.
    If a cycle is detected while attempting to expand the values, then an
    exception is thrown.

    \%strs  Reference to a hash containing variables to expand

    \%overlay
            Reference to a hash containing other variable values

    Returns Nothing

SEE ALSO
    *   String::Interpolate - Wrapper for builtin the Perl interpolation
        engine

AUTHOR
    Paul Evans <leonerd@leonerd.org.uk>

lib/String/Expand.pm  view on Meta::CPAN

   $str =~ s{\\([\\\$])|$VARNAME_MATCH}
            {     $1  or expand_one_var( $2, $vars )}eg;

   return $str;
}

sub expand_strings_inner($$$$);

sub expand_strings_one_var($$$$)
{
   my ( $var, $strs, $overlay, $done ) = @_;

   # Chop off delimiting {braces} if present
   $var =~ s/^\{(.*)\}$/$1/;

   if( exists $strs->{$var} ) {
      return $strs->{$var} if( $done->{$var} );
      # Detect loops
      if( exists $done->{$var} ) {
         croak "Variable loop trying to expand '$var'";
      }
      $done->{$var} = 0;
      expand_strings_inner( $strs, $overlay, $var, $done );
      return $strs->{$var};
   }

   return $overlay->{$var} if( exists $overlay->{$var} );
   
   croak "Unknown variable '$var'";
}

sub expand_strings_inner($$$$)
{
   my ( $strs, $overlay, $v, $done ) = @_;
   
   if( $strs->{$v} =~ m/[\\\$]/ ) {
      $strs->{$v} =~ s{\\([\\\$])|$VARNAME_MATCH}
                      {     $1  or expand_strings_one_var( $2, $strs, $overlay, $done )}eg;
   }

   $done->{$v} = 1;
}

=head2 expand_strings( \%strs, \%overlay )

This function takes a hash of strings, and expands variable names embedded in
any of them, in the same form as the string passed to C<expand_string()>.
Expansions may refer to other strings, or to values in the C<I<%overlay>>
hash. Values in the main variables hash take precidence over values in the
overlay.

Where values refer to other values, care must be taken to avoid cycles. If a
cycle is detected while attempting to expand the values, then an exception is
thrown.

=over 8

=item \%strs

Reference to a hash containing variables to expand

=item \%overlay

Reference to a hash containing other variable values

=item Returns

Nothing

=back

=cut

sub expand_strings($$)
{
   my ( $strs, $overlay ) = @_;

   # 0: a variable expansion is in progress
   # 1: value has been correctly expanded
   my %done;

   foreach my $v ( keys %$strs ) {
      expand_strings_inner( $strs, $overlay, $v, \%done );
   }
}

# Keep perl happy; keep Britain tidy
1;

__END__

=head1 SEE ALSO

t/03strings.t  view on Meta::CPAN

expand_strings( \%s, { ONE => 1, TWO => 2 } );
is_deeply( \%s, { foo => 'one is 1', bar => 'two is 2' }, 'Independent strings' );

%s = ( dollar => '\$', slash => '\\\\', combination => 'dollar is \$, slash is \\\\' );
expand_strings( \%s, {} );
is_deeply( \%s, { dollar => '$', slash => '\\', combination => 'dollar is $, slash is \\' },
           'Strings with literals' );

%s = ( foo => 'bar is ${bar}', bar => 'quux' );
expand_strings( \%s, {} );
is_deeply( \%s, { foo => 'bar is quux', bar => 'quux' }, 'Chain of strings (no overlay)' );

%s = ( foo => 'bar is ${bar}', bar => 'quux is ${quux}' );
expand_strings( \%s, { quux => 'splot' } );
is_deeply( \%s, { foo => 'bar is quux is splot', bar => 'quux is splot' }, 'Chain of strings (with overlay)' );

%s = ( foo => '${foo}' );
dies_ok( sub { expand_strings( \%s, {} ) },
         'Exception (loop) throws exception' );

%s = ( foo => 'bar is ${bar}', bar => 'quux' );
expand_strings( \%s, { bar => 'splot' } );
is_deeply( \%s, { foo => 'bar is quux', bar => 'quux' }, 'Chain with overlay' );



( run in 2.305 seconds using v1.01-cache-2.11-cpan-49f99fa48dc )