http://qs321.pair.com?node_id=62737

Faidros has asked for the wisdom of the Perl Monks concerning the following question: (object-oriented programming)

With a normal sub I can do this:
$ref = \&MyFunc;
..which will make $ref a reference to the sub MyFunc. But how do I do it if MyFunc is a method in the $self object? I want to make a reference to $self->MyFunc so $self is passed when I call it, but neither
$ref = \&$self->MyFunc;
nor
$ref = \$self->MyFunc;
seems to work. Perl says "Undefined subroutine" for the first, and "not a CODE reference" for the second. So, question is, how do I reference a method so the object is sent when I call the reference, or is there a workaround for the problem?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How do I reference methods?
by Joost (Canon) on May 24, 2002 at 16:39 UTC
    you can use the UNIVERSAL::can method:

    my $object = Ojbect->new; # normal call $object->call(); # get ref my $ref = $object->can('call'); $ref->($object); # use reference..

    This will also follow normal inheritance rules.

    Note: you probably need to use the object you want to call as the first argument, because normal object methods expect $self to be the first arguments. (that's what $object->call() does anyway)...

Re: How do I reference methods?
by RocketInABog (Initiate) on Dec 23, 2008 at 12:45 UTC

    Though there are other interesting ways of getting a method reference, there already exists an equivalently straightforward way of doing this.

    $ref = \&Class::method; $instance = new Class; $ref->( $instance, @args ); # - calls method of Class for the given i +nstance
Re: How do I reference methods?
by LanX (Saint) on Dec 23, 2008 at 12:54 UTC
    Many complicated ways of calling the reference to a method have been proposed. This one is easier and straightforward.
    $obj->$ref2meth(...paras...);
    Unfortunately the documentation is lousy, that's why it's fairly unknown! For more details please see OOP: Obj->Coderef for calling Private Methods
Re: How do I reference methods?
by mirod (Canon) on Mar 07, 2001 at 18:09 UTC

    You can use closures:

    #!/bin/perl -w use strict; # just a simple package package obj; sub new { return bless {content => $_[0]}; } sub print { my $self= shift; print ref($self), ": ", $self->{content}, " - ", @_, "\n"; } # now the main stuff package main; my $p; # that's your method reference { my $o= obj::new( "toto"); # the normal way: create $o->print( "tata"); # print $p=sub { $o->print(@_); }; # create the closure (an anon sub) $p->( "titi"); # use it to print $o= obj::new "foo"; # change the object $p->("tutu"); # print using the new object } my $o= obj::new "bar"; # the $o used with the closure is not # in scope any more $p->("tutu"); # but $p still uses it

    This returns:

    obj: toto - tata obj: toto - titi obj: foo - tutu obj: foo - tutu

    Note that as far as convenience goes calling $o->print or $p->print is pretty similar ;--)

Re: How do I reference methods?
by davorg (Chancellor) on Mar 07, 2001 at 17:07 UTC

    All very kludgy, but you could do something like the following. Remember that the first parameter to an object method must be a reference to an object of the right type.

    #!/usr/bin/perl -w use strict; package Thing; sub new { bless {}, shift; } sub say { print "@_[1 .. $#_]\n"; } package main; my $thing = Thing->new; $thing->say('Hello', 'World'); my $say = \&Thing::say; $say->($thing, 'Goodbye', 'All');
Re: How do I reference methods?
by ariels (Curate) on Aug 20, 2001 at 17:34 UTC
    See my note on pointers to member functions.

    That code lets you say:

    use PMF; my $p = PMF->new('print'); $p->$o(123); # Call $o->print(123) $p->$x('a','b'); # Call $x->print('a','b') $p->$z(); # Call $z->print
Re: How do I reference methods?
by Anonymous Monk on May 24, 2002 at 11:31 UTC
    Another stupid way:
    use obj; $o = new obj; $ref = sub{$o->method(@_)}; #so if you want to call ref: #&ref('arg1','arg2'[,...]);