String-Expand

 view release on metacpan or  search on metacpan

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

variable expansions in all the values in a given hash, where values can refer
to other values within the same hash. 

=cut

=head1 FUNCTIONS

=cut

sub expand_one_var($$)
{
   my ( $var, $vars ) = @_;

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

   unless( defined $vars->{$var} ) {
      croak "Unknown variable '$var'";
   }

   return $vars->{$var};
}

=head2 $expanded = expand_string( $str, \%vars )

This function expands embedded variable references in the passed string, and
returns the expanded copy. 

=over 8

=item $str

A string possibly containing variable expansions

=item \%vars

Reference to a hash containing variable values

=item Returns

A string with variables expanded

=back

=cut

sub expand_string($$)
{
   my ( $str, $vars ) = @_;

   $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

=over 4

=item *

L<String::Interpolate> - Wrapper for builtin the Perl interpolation engine

=back

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>



( run in 1.001 second using v1.01-cache-2.11-cpan-e1769b4cff6 )