tags:

views:

71

answers:

3

I'm trying to figure out how to make a function reference work for a Perl module. I know how to do it outside of a module, but inside one? Consider code like this:

==mymodule.pm==
1 sub foo { my $self = shift; ... }
2 sub bar { my $self = shift; ... }
3 sub zip {
4   my $self = shift;
5   my $ref = \&foo;
6   $self->&$foo(); # what syntax is appropriate?
7 }
==eof===

Look at lines 5-6 above. What's the correct syntax for (1) defining the function reference in the first place, and (2) dereferencing it?

Thanks,

--Steve

+5  A: 

If $ref is a method (expects $self as first argument) and you want to call it on your $self, the syntax is:

$self->$ref(@args)
Randal Schwartz
The important thing to note in this calling style is that `$self` is not used to determine which method to call (as is usually the case when calling a method OO-style) -- the method is determined solely from `$ref`, and `$self` is merely passed as $ref's first argument. Contrast this to if `$ref` was simply the name of a method, in which case we would start looking for that method on `$self` and then up the inheritance tree.
Ether
Upvoted for being Randal "one-L" Schwartz! Yay!
Jonathan Feinberg
@Jonathan: let's not turn SO[perl] into a group of salivating groupies.. the Jon Skeet fanboys are bad enough. :/
Ether
OMG, are you *the* Ether!?
Jonathan Feinberg
*I have a dream*, where answers are voted upon based on their content, and not by person that posted it.
Brad Gilbert
+2  A: 

TMTOWTDI

Defining a function reference:

$ref = \&subroutine;
$ref = sub { BLOCK };
$ref = "subroutineName"; # or $ref = $scalarSubroutineName

Dereferencing:

$ref->(@args);
&$ref;  
&{$ref}(@args);
mobrule
+3  A: 

Use the following:

$self->$ref();

With this syntax, $ref can be a reference to a subroutine or even a string with the name of the method to call, e.g.,

my $ref = "foo";
$self->$ref();

Be aware that the two have slightly different semantics with respect to inheritance.

When you aren't passing explicit arguments, the parentheses are optional:

$self->$ref;  # also flies

Otherwise, use

$self->$ref($arg1, \%arg2, @others);
Greg Bacon