Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re (tilly) 1: Why I hate File::Find and how I (hope I) fixed it

by tilly (Archbishop)
on Aug 30, 2001 at 18:11 UTC ( #109079=note: print w/ replies, xml ) Need Help??


in reply to Why I hate File::Find and how I (hope I) fixed it

In fact you have hit on the classic way that you extend a functional system. Instead of passing around more information or creating global data, just move that action into creating a closure which binds the arguments up front for later use.

For an example with many of these closures running around in parallel, see Re (tilly) 1: 5x5 Puzzle. (Look specifically at ret_toggle_square.) And a more general form of your make_wanted function would be:

# Takes an anon function and a list of arguments. Returns # a closure which will call the anon function with those # arguments prepended to the argument list. sub bind_args { my ($sub, @args) = @_; return sub {$sub->(@args, @_);}; }


Comment on Re (tilly) 1: Why I hate File::Find and how I (hope I) fixed it
Download Code
Generating similar functions in unrelated objects
by t'mo (Pilgrim) on Aug 31, 2001 at 02:03 UTC

    Suppose you wanted to do something like this to a family of related objects. How would you assign the anonymous function to be a method of each class? (I can do that trick in JavaScript using ObjectName.prototpye.methodName, but how would I do that in Perl?)

    For example, what I would like to do is:

    ... sub ObjectToString { my $name = shift; return sub { my $s = $name . $self->getParametersAndValues(); return $s; } } ... package Fu; sub toString = ObjectToString("Fu"); ... package Bar; sub toString = ObjectToString("Bar"); ... package Baz; sub toString = ObjectToString("Baz"); ...

    Then I would use it like this:

    my ($foo, $bar, $baz); $foo = Fu->new(); # do stuff with foo... print $foo->toString(); $bar = Bar->new(); # do stuff with bar... print $bar->toString(); ...

    The obvious answer here is to use Inheritance™, but what if, for some reason, I don't want to use inheritance? Can I still accomplish what I want to?

      You would want to do a typeglob assignment. If you assign an anonymous function to a typeglob, you define that function. Like this:
      package Stringify; sub objectToString { my $name = shift; return sub { $name . (shift)->getParametersAndValues(); }; } # Time passes package Fu; *toString = Stringify::objectToString("Fu");
      But I should note that you can make this nicer with overload and an autogenerated method. For instance:
      package Stringify; use strict; use Carp; sub import { my $pkg = caller(); my $code = qq( # A trick for custom error reporting - see perlsyn. \n# line 1 "'Autogenerated for $pkg by Stringify'" package $pkg; use overload '""' => sub { __PACKAGE__ . (shift)->getParametersAndValues(); }; ); eval($code); if ($@) { confess("Cannot autogenerate stringification for package '$pkg': $ +@ The code is:\n$code"); } } 1;
      would allow you to simply:
      package Fu; use Stringify; # Use objects as strings, and they stringify
      If you want you could create an autogenerated function called toString and pass a reference to that function to overload.

        You know what happened, don't you? Just as I was leaving the building, not more than five minutes after I asked the question, the answer came to me: symbol table. :-)

        The import approach is interesting. It gives me more food for thought, especially in relation to this question I asked about writing your own import. Thanks.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (8)
As of 2015-07-06 21:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (83 votes), past polls