[Israel.pm] Implicit $self variable without Source Filters
Yuval Kogman
nothingmuch at woobling.org
Tue Nov 7 13:09:09 EET 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