Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^4: searching for an object reference

by simonm (Vicar)
on Jul 09, 2005 at 00:24 UTC ( [id://473618]=note: print w/replies, xml ) Need Help??


in reply to Re^3: searching for an object reference
in thread searching for an object reference

A further level of abstraction and optimization can be provided by custom-compiling a subroutine optimized to perform the necessary task:
use strict; use UNIVERSAL 'isa'; sub build_deep_sub { my %options = @_; my $sub = q/ sub / . ( $options{proto} ? "($options{proto})" : '' ) +. q/ { / . ( $options{init} ) . q/ my ( @results, %seen ); while ( scalar @_ ) { my $target = shift; / . ( $options{guard} ? "next unless grep { $options{guard} } \$ +target;" : "" ) . q/ push @results, / . ( $options{map} ) . q/ $target; / . ( $options{post_order} ? 'push' : 'unshift' ) . q/ @_, / . ( $options{guard} ? " grep { $options{guard} }" : "" ) . q/ $seen{$target} ++ ? () : isa($target, 'HASH') ? %$target : isa($target, 'ARRAY') ? @$target : isa($target, 'REF') ? $$target : isa($target, 'SCALAR') ? $$target : (); } @results; } /; eval $sub or die "$@: $sub"; } my $type_search = build_deep_sub( init => 'my $type = shift;', map => +'grep isa( $_, $type ), ', guard => 'ref($_)' ); my @loggers = $type_search->( 'Log', $target );

The speed improvement of eliminating a round of subroutine calls will outway the one-time cost of the string eval unless your data structure to be searched is very small.

A library based on this approach could pre-generate a number of generally useful subroutines:

*{'deep_walk'} = build_deep_sub(); *{'deep_map'} = build_deep_sub( init => 'my $test = shift;', map => +'map $test->($_),' ); *{'deep_grep'} = build_deep_sub( init => 'my $test = shift;', map => + 'grep $test->($_),' ); *{'deep_grep_refs'} = build_deep_sub( init => 'my $test = shift;', m +ap => 'grep $test->($_),', guard => 'ref($_)' ); *{'deep_grep_type'} = build_deep_sub( init => 'my $type = shift;', m +ap => 'grep isa( $_, $type ), ', guard => 'ref($_)' );

(For what it's worth, the prototypes generated above don't seem to be quite right, but I'm sure that could be figured out with a bit of experimentation.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://473618]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-03-28 20:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found