Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Pointers to member functions

by ariels (Curate)
on Aug 20, 2001 at 17:28 UTC ( #106214=snippet: print w/replies, xml ) Need Help??
Description: Remember ::* and ->* from C++? If you do, you probably hate them.

A pointer to a member function lets you store a particular method in a variable and then apply it to objects. Here's how to get them in Perl.

It's a bit long, but almost all of it isn't code...

# Perl "pointer to member function" abstraction

package PMF;

use strict;
use Carp;

sub new {
  my ($class,$name) = @_;
  $name =~ /^[A-Za-z0-9_]\w*$/ or croak "Bad method name \"$name\"";
  bless eval <<"END_CODE", $class;
    sub {
      my \$self = shift;

sub call {
  my $self = shift;

package PMF::able;

sub call {            # permute our args
  my $self = shift;
  my $pmf = shift;

=head1 NAME

PMF - pointer to member function in Perl


    my $p = PMF->new('print');
    my $x = ClassWithPrintMethod->new(17);
    $p->($x, 'foo');           # call $x->print('foo')
    $p->call($x, 'foo');       # call $x->print('foo') in another way

    package MyClass;
    use vars qw/@ISA/;
    @ISA = qw/PMF::able/;
    # ...

    package main;
    my $y = MyClass->new('xyz');
    $y->call($p, 42);          # call $y->print(42)


C<PMF> gives you pointers to member functions.  A PMF is the
abstraction of calling a particular method of an object, similar to
the C<::*> / C<-E<gt>*> mess of C++.

To create a PMF, pass C<new> the name of the method you want to
call. C<PMF::new> creates a code object that calls that method of any
object (contrast C++ pointers to member functions, which are
restricted to subclasses of some root class).  Lacking a better
dispatch syntax, you apply a PMF C<$pmf> to an object C<$obj> by
saying C<$pmf-E<gt>($obj, I<args...>)>.


If you would rather say C<$obj-E<gt>call($pmf, I<args...>)>, you need
to make the class of C<$obj> inherit from the mixin class
C<PMF::able>, which provides exactly this C<call> method.

If you wish to avoid changing the class of C<$obj>, you can still use
the alternate syntax by creating your objects in an appropriate dummy

    package MyClass2;
    use vars qw/@ISA/;
    @ISA = qw/ClassWithPrintMethod PMF::able/;
    # empty package body!

    package main;
    my $z = MyClass2->new(19);
    $z->call($p, 'foo');

=head1 NOTES / BUGS

=over 4

=item *

A PMF is not really an object.  It I<is> blessed into the class
C<PMF>, but has no methods except C<call>!

=item *

The syntax is horrible.  At least it is not as bad as in C++.

=item *

C<PMF::able> is probably more confusing than useful.

=head1 AUTHOR

Ariel Scolnicov C<E<lt><gt>>


Replies are listed 'Best First'.
Re: Pointers to member functions
by japhy (Canon) on Aug 20, 2001 at 18:55 UTC
    What about:
    $meth = $obj->can($method_name); $meth->($obj, @args);

    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Also note that using a function reference with the method syntax works just fine. Consider the following example where an unnamed method is called from an object in a class with no methods of its own:
      my $foo = bless {}, "bar"; my $meth = sub {shift; print shift}; $foo->$meth("Sneaky");
      (Yeah, I know you know that, but others might find it neat.)
Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://106214]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2017-05-01 07:20 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (545 votes). Check out past polls.