Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

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;
      \$self->$name(\@_)
    }
END_CODE
}

sub call {
  my $self = shift;
  $self->(@_)
}


package PMF::able;

sub call {            # permute our args
  my $self = shift;
  my $pmf = shift;
  $pmf->($self,@_);
}



=head1 NAME

PMF - pointer to member function in Perl

=head1 SYNOPSIS

    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)

=head1 DESCRIPTION

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

=head1 ALTERNATE CALLING SYNTAX

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
class:

    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>ariels@compugen.co.ilE<gt>>

=cut


1;
Comment on Pointers to member functions
Download Code
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.)

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://106214]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2014-12-18 23:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (67 votes), past polls