use strict;
use warnings;
use Data::Dumper;
# test data
my $data = {
test => {
foo => { bar => 'bar',
baz => 'baz',
bul => { foo => { bar => 'bul' } } },
bar => { baz => 'baz' },
},
foo => { bar => 'foo' },
};
my $found = rec_data('->{foo}->{bar}', $data);
print Dumper($found);
print "--- array of ref's ---\n";
print "$_\n" for @$found;
# verify by hand
print "--- verify by hand ---\n";
print \$data->{foo}->{bar}, "\n",
\$data->{test}->{foo}->{bar}, "\n",
\$data->{test}->{foo}->{bul}->{foo}->{bar}, "\n";
sub rec_data
{
my ($pattern, $data) = @_;
return if ref($data) ne 'HASH';
my @keys = keys %$data; # persist the value of the keys
return if !@keys;
my @found;
# do we see pattern?
if (eval 'exists $data' . $pattern) {
push @found, eval '\$data' . $pattern;
}
# traverse the 'children'
# foreach (keys %$data) will not work and will result
# in deep recursion
foreach (@keys) { # get the value of each key
my $result = rec_data($pattern, $data->{$_});
next if ! $result;
push @found, @$result;
}
return(\@found);
}
And the output is -
$VAR1 = [
\'foo',
\'bar',
\'bul'
];
--- array of ref's ---
SCALAR(0x167bdc)
SCALAR(0x167b4c)
SCALAR(0xf4a50)
--- verify by hand ---
SCALAR(0x167bdc)
SCALAR(0x167b4c)
SCALAR(0xf4a50)
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.