Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: Canon concerning coderef calls?

by tmoertel (Chaplain)
on Nov 15, 2004 at 19:43 UTC ( [id://407929]=note: print w/replies, xml ) Need Help??


in reply to Canon concerning coderef calls?

Try replacing your loop with this:
$::{$_}->($_) foreach @list;

Seems to do the trick:

Sub one reporting for duty. Sub two reporting for duty. Sub three reporting for duty.

Cheers,
Tom

Replies are listed 'Best First'.
Re^2: Canon concerning coderef calls?
by NetWallah (Canon) on Nov 15, 2004 at 19:54 UTC
    Very cool, Tom (I learned something!).

    Here is another alternative:

    foreach my $MySubName (@list) { ## &{\&$MySubName}($MySubName); # This works! ## $::{$MySubName}($MySubName); # This (tmoertel) is better. no strict qw(refs); &{*$MySubName}($MySubName); # Use GLOB - Also cool! #Chromatic's OO way -- #can(METHOD) # can checks to see if its object has a method called METHOD, # if it does then a reference to the sub is returned, i # if it does not then undef is returned. # main->can($MySubName)->($MySubName); }
    Update:Added Chromatic's OO-Style + Doc

        Earth first! (We'll rob the other planets later)

      Chromatic's OO way

      I wouldn't really call that an OO way. Sure, it uses can as a class method on main, but that's where the OOishness ends. It returns a plain coderef and executes it with a different dereferencing syntax than you used. I believe it is also the only alternative that does not use a symbolic reference.

      To reinforce the point about being a plain coderef, this works:

      foreach (@list) { my $coderef = main->can($_); &$coderef($_); }

      And this does too, if you really want to get rid of all the pointy arrows:

      foreach (@list) { my $coderef = UNIVERSAL::can('main', $_); &$coderef($_); }

      Update: and if you want to see what I would consider the "OO way":

      foreach (@list) { main->$_($_); }

      But, frankly, I think that's very ugly. It uses a symbolic reference too. I would use can as chromatic originally did.

        I agree with all your notes, revdiablo.

        I particularly like the self-documenting "UNIVERSAL::can" call, although research shows that the "can" method (or allegedly exported sub) does not really exist in any module - documentation says it is built into perl.

            Earth first! (We'll rob the other planets later)

Re^2: Canon concerning coderef calls?
by jobi (Scribe) on Nov 15, 2004 at 20:00 UTC

    This works beautifully, but this novice is at a loss to understand why.

    Is not $:: an indicator that the sub is in the main package? So that $::{$_} is the subroutine $_ in the main package? And then that is called with the arguments $_?

    Why does this allow us to do the referencing/dereferencing in one step, is this novice missing something here?

      Yes - you have understood the sequence correctly.

      The relevant document is the "Symbol Table" section of perlmod.

      The symbol table for a package happens to be stored in the hash of that name with two colons appended. The main symbol table's name is thus %main::, or %:: for short. ...

      Hence "$::" is de-referencing the "%main::" hash, using "$_" as the key. The following parens prvide the "sub" context, and allow the sub to be passed the $_ param.

          Earth first! (We'll rob the other planets later)

        Ah, so that's how it works...

        I didn't realize that the main package was named %main and not $main, so I didn't see the dereference there.

        Thank you for taking the time to explain, and thanks to tmoertel for granting us his wisdom in the first place.

        jobi - a little bit wiser now.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-04-24 22:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found