[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:
<<<<<<<<<<<
#!/usr/bin/perl
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;
}
add_implicit_self('print_message');
add_implicit_self('set_message');
package main;
my $o1 = MyClass->new("Hello");
$o1->print_message();
my $o2 = MyClass->new("Naomi");
$o2->print_message(1);
$o2->print_message();
$o1->set_message("Yowza");
$o1->print_message(1);
>>>>>>>>>>>
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.
Regards,
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