You can see I parse my variables a little differently. If it's more complex for you, then so be it, but I used simple cases. I used the $+ variable because I want to match the string INSIDE quotes (not the quotes themselves) or else an un-quoted string, and I don't know which of these matches, so $+ gives me the last matching capture group. It's like writing defined($2) ? $2 : $3 in this case, but I didn't want to do that.#!/usr/bin/perl use strict; use warnings; my %vars; my %depend; while (<DATA>) { chomp; if (/^\s*(\w+)\s*=\s*(?:"([^"]*)"|(.*))/) { my ($name, $val) = ($1, $+); $vars{$name} = $val; $depend{$name} = [ $vars{$name} =~ /\$(\w+)/g ]; } } expand(\%vars, \%depend); sub expand { my ($varhash, $dephash, $queue) = @_; $queue ||= [ keys %$varhash ]; # for each item in the queue for (@$queue) { # make sure its dependencies are expanded expand($varhash, $dephash, $dephash->{$_}); # then interpolate the variables in this item $varhash->{$_} =~ s/\$(\w+)/$varhash->{$1}/g; } } use Data::Dumper; print Dumper(\%vars); __DATA__ VAR1 = "say $VAR2" VAR2 = "hi $VAR3" VAR3 = jeff
You can see how expand() looks similar to the post-order traversal code I showed you a day or two ago. It's a similar concept. The function, when called with only the two hashrefs, uses the keys of the %vars hash as its queue. Each recursive call uses the dependent variables of the current one as its queue. I hope it's understandable.
In reply to Re: Re: Re: simulating bash
by japhy
in thread simulating bash
by agaffney
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |