LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   method references in perl (https://www.linuxquestions.org/questions/programming-9/method-references-in-perl-316675/)

mschutte 04-24-2005 11:27 AM

method references in perl
 
Hi! I am trying to create a hard reference to a method bound to an object (yes, blessed reference) with perl, while 'use strict' is on. I am not able to find the correct syntax, neither
\&$self->method
nor
\&{$self->method}
compile. Can anybody help me?

Thanks, mschutte

puffinman 04-24-2005 01:25 PM

You can call a method stored in a variable by just putting the variable in the place you'd normally put the name of the method. For instance:

Code:

# say you've got an $object, and a method poke_me
# which sometimes takes an argument

my $method_ref = "poke_me";

$object->$method_ref;
# calls $object->poke_me

#or with an argument
$object->$method_ref("really hard")
# calls $object->poke_me("really hard")


mschutte 04-25-2005 10:05 AM

Well, great stuff, but it's not what I need. Using this method, I still have to tell the blessed ref to operate on. Probably you understand what I mean if I explain what I need it for.

I am using XML::Parser in a class and want to assign the handlers to some methods. This means:
my $expat = new XML::Parser(Handlers => { Start => \&startElement });
but with a method instead of a function call:
my $expat = new XML::Parser(Handlers => { Start => \&$self->startElement });
when $self is a blessed reference. It doesn't work. Is there any way to make it work? If yes, please post a reply...

Thanks, mschutte

puffinman 04-25-2005 12:25 PM

Ah, I see. Ok, well depending on whether you want to call the method as an object method or a class method, it will be different. If the method you want to call is dependent on the object's state, you want the object call, and you'd do it with a closure, like this:

Code:

my $object = Whatever->new;

my $expat = XML::Parser->new(Handlers => { Start => sub {$object->method} });

Here, the closure ( sub {$object->method} ) will "remember" the object for its (the closure's) entire life, even if the object goes out of scope elsewhere. If you want to call a class method, not bound to any particular instance of the class, try this:

Code:

my $object = Whatever->new;

my $expat = XML::Parser->new(Handlers => { Start => \&Whatever::method} });

Note that using fully qualified method names like this can be problematic with inherited classes. Using \&Whatever->method may also work, I'm not sure. You could also embed Whatever->method in a closure as in the first example. Please note the distinction, however, between Whatever->method and $object->method.

To anyone reading this, I highly recommend learning to use closures, they can be incredibly powerful and elegant solutions.

mschutte 04-26-2005 09:46 AM

Yes, really elegant. Thank you!

-- mschutte


All times are GMT -5. The time now is 10:00 PM.