[Israel.pm] Implicit $self variable without Source Filters

Shlomi Fish shlomif at iglu.org.il
Mon Nov 6 11:34:59 PST 2006

Hi all!

During the last meeting we discussed the fact that Moose was pretty cool, but 
it still didn't have the Spiffy feature in which one does not have to write 
my $self = shift; at the beginning of methods. Now Spiffy uses a source 
filter for this.

Today this made me think whether it can be achieved without a source filter. 
And indeed it can. By wrapping the method in a closure which localises $self 
to the first argument (and passes the rest to the closure), one can have an 
implicit $self. Here's the code:


use strict;
use warnings;

package MyClass;

sub new
    my $class = shift;
    my $self = {};
    bless $self, $class;
    $self->{msg} = shift;

    return $self;

our $self;

sub add_implicit_self
    my $sub_name = shift;
    my $sub_ref = \&{$sub_name};
        no strict 'refs';
        no warnings 'redefine';

        ${__PACKAGE__."::"}{$sub_name} = sub {
            local $self = shift;
            return $sub_ref->(@_);

sub print_message
    my $uc = shift;

    my $msg = $self->{msg};
    if ($uc)
        $msg = uc($msg);

    print "$msg\n";

sub set_message
    $self->{msg} = shift;


package main;

my $o1 = MyClass->new("Hello");

my $o2 = MyClass->new("Naomi");


The downsize of this is that $self is a global and that the SUPER, NEXT, etc. 
meta-methods may be broken. But I still think it's pretty cool.


	Shlomi Fish

Shlomi Fish      shlomif at iglu.org.il
Homepage:        http://www.shlomifish.org/

Chuck Norris wrote a complete Perl 6 implementation in a day but then
destroyed all evidence with his bare hands, so no one will know his secrets.

More information about the Perl mailing list