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

Yuval Kogman nothingmuch at woobling.org
Tue Nov 7 03:09:09 PST 2006


This breaks 'caller'. If you use Sub::Uplevel then it sometimes also
breaks, and there's a runtime cost.

Look on perl5-porters for clkao's new selfless module, which uses a
localization stack hack to keep the localized variables without the
extra stack frame.

It uses a technique similar to yours, but without the issues
involved.

Cheers,

On Mon, Nov 06, 2006 at 21:34:59 +0200, Shlomi Fish wrote:
> 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.
> _______________________________________________
> Perl mailing list
> Perl at perl.org.il
> http://perl.org.il/mailman/listinfo/perl

-- 
  Yuval Kogman <nothingmuch at woobling.org>
http://nothingmuch.woobling.org  0xEBD27418

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://perl.org.il/pipermail/perl/attachments/20061107/f4dd5afc/attachment.pgp 


More information about the Perl mailing list