Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

How do I reference methods?

( #62737=categorized question: print w/ replies, xml ) Need Help??
Contributed by Faidros on Mar 07, 2001 at 16:50 UTC
Q&A  > object-oriented programming


Description:

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?

Answer: How do I reference methods?
contributed by Joost

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)...

Answer: How do I reference methods?
contributed by RocketInABog

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
Answer: How do I reference methods?
contributed by mirod

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 ;--)

Answer: How do I reference methods?
contributed by LanX

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
Answer: How do I reference methods?
contributed by ariels

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
Answer: How do I reference methods?
contributed by Anonymous Monk

Another stupid way:

use obj; $o = new obj; $ref = sub{$o->method(@_)}; #so if you want to call ref: #&ref('arg1','arg2'[,...]);
Answer: How do I reference methods?
contributed by davorg

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');

Please (register and) log in if you wish to add an answer



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others musing on the Monastery: (7)
    As of 2014-08-23 07:57 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The best computer themed movie is:











      Results (172 votes), past polls