Easy. Change map_recursive() to not descend into recognized
structures. That is probably the more sensible default
behavior, agreed.
#!/usr/bin/perl -w
use strict;
sub map_recursive {
my ($structure, $predicate) = @_;
# don't descend into recognized structures
if ($predicate->($structure)) {
return $predicate->($structure);
}
# not recognized - pick apart
my @result;
if (UNIVERSAL::isa($structure, 'ARRAY')) {
for (@{$structure}) {
push @result, map_recursive($_,
$predicate);
}
} elsif (UNIVERSAL::isa($structure, 'HASH')) {
for (keys %{$structure}) {
push @result, map_recursive($structure->{$_},
$predicate);
}
} else {
push @result, $predicate->($structure);
}
return @result;
}
package Foo;
sub new { bless {}, shift }
sub get { $_[0]->{$_[1]} }
sub set { $_[0]->{$_[1]} = $_[2] }
package main;
my @list = (Foo->new, Foo->new, Foo->new);
$list[0]->set('a', 'b');
$list[1]->set('b', 'a');
$list[2]->set('x', 'y');
my $isa_foo = sub { UNIVERSAL::isa(shift, 'Foo') };
print "#1: ", join(',', map_recursive(\@list, $isa_foo)), "\n";
my @list2 = ( {a => 'm'}, { 1 => 55}, { Foo => 'Bar' });
my $h = sub { UNIVERSAL::isa(shift, 'HASH') };
print "#2: ", join(',', map_recursive (\@list2, $h)), "\n";
Christian Lemburg
Brainbench MVP for Perl
http://www.brainbench.com