Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

a selfless implementation

0 views
Skip to first unread message

Chia-liang Kao

unread,
Nov 5, 2006, 4:22:32 AM11/5/06
to perl5-...@perl.org

While discussing some evil today with Jesse, I went to make a proof of
concept selfless.pm, which does "my $self = shift" for you.

I know there are several implementations of this, which requires either
source filter or deep magic. But this one is surprisingly clean to me,
which seems too good to be true, so I wonder if I am missing something
obvious. The only magic it needs is forget_unlocal in Data::Bind.

Basically what this does is create package variable "$self" for the
caller during import. on init time, it walks the functions defined in
the modules that wants selfless, and wrap them with local $self = shift,
forget_unlock it for 1 level, and goto the original coderef. And this
is not using lexwrap so we don't have the caller() runtime penalty.

Attached is a quick implementation that segfaults randomly and doesn't
collect the functions actually defined in the pacakge correctly. But if
we can get the forget_unlocal semantics defined and supported, maybe we
can have use features 'methods'.

(I might just be crazy and should probably go to bed)

Cheers,
CLK

selfless.pm

Randal L. Schwartz

unread,
Nov 5, 2006, 9:58:55 AM11/5/06
to perl5-...@perl.org
>>>>> "Chia-liang" == Chia-liang Kao <cl...@bestpractical.com> writes:

Chia-liang> Basically what this does is create package variable "$self" for
Chia-liang> the caller during import. on init time, it walks the functions
Chia-liang> defined in the modules that wants selfless, and wrap them with
Chia-liang> local $self = shift, forget_unlock it for 1 level, and goto the
Chia-liang> original coderef. And this is not using lexwrap so we don't have
Chia-liang> the caller() runtime penalty.

The problem with this is that a package rarely has *only* methods.
You need some way to say "this subroutine is a method" vs "that subroutine
is being used as an ordinary subroutine". By the time you do that,
you can do what you want with attributes or source filters.

I'd certainly not be using your selfless module, nor recommending it as
merely more than just a "interesting hack".

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<mer...@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Steffen Mueller

unread,
Nov 5, 2006, 10:25:40 AM11/5/06
to Chia-liang Kao, perl5-...@perl.org
Hi,

Chia-liang Kao schrieb:

Well, forget_unlock is not the only magic it needs. I would consider
INIT blocks reasonably magical, too, since they won't work in PAR
packaged programs. I know I'm biased and this is really a PAR bug, not a
perl bug, but if module authors started using lots and lots of modules
which use INIT and break without it, the combination of PAR+CPAN would
become rather worthless.

That point aside, I like the idea. I wouldn't even consider Randal's
(valid) point prohibitive: If you're doing OOP, your packages should
*rather not* provide both subroutines and methods. That's just a matter
of preference, though. I would suggest separating the package into a
pure class and a subroutine-providing package anyway.

Steffen

P.S.:
To fix this bug, someone with XS-fu would have to help out. Ping me if
you (as in: any reader) have some time to spare.

Rafael Garcia-Suarez

unread,
Nov 5, 2006, 2:00:55 PM11/5/06
to Steffen Mueller, Chia-liang Kao, perl5-...@perl.org
On 05/11/06, Steffen Mueller <rt83...@sneakemail.com> wrote:
> Well, forget_unlock is not the only magic it needs. I would consider
> INIT blocks reasonably magical, too, since they won't work in PAR
> packaged programs. I know I'm biased and this is really a PAR bug, not a
> perl bug, but if module authors started using lots and lots of modules
> which use INIT and break without it, the combination of PAR+CPAN would
> become rather worthless.

UNITCHECK blocks can help here.

Michael G Schwern

unread,
Nov 5, 2006, 2:35:27 PM11/5/06
to Steffen Mueller, Chia-liang Kao, perl5-...@perl.org
Steffen Mueller wrote:
> Well, forget_unlock is not the only magic it needs. I would consider
> INIT blocks reasonably magical, too, since they won't work in PAR
> packaged programs. I know I'm biased and this is really a PAR bug, not a
> perl bug, but if module authors started using lots and lots of modules
> which use INIT and break without it, the combination of PAR+CPAN would
> become rather worthless.

Do not hamstring all your code to work around broken tools. Fix the tools.

Vadim

unread,
Nov 4, 2006, 12:19:10 PM11/4/06
to Chia-liang Kao, perl5-...@perl.org
Chia-liang Kao wrote:

>While discussing some evil today with Jesse, I went to make a proof of
>concept selfless.pm, which does "my $self = shift" for you.
>
>

I think this is just taking your gun directly to your foot.
Perl allow this, but no doubt you *will* shoot the foot.

Very dangerous concept.
The sooner you'll refuse the better.

If you need flexible OO approach, then go to perl6, which is better and
better these days.


>I know there are several implementations of this, which requires either
>source filter or deep magic.
>

all source filters are deprecated.
Except simplies source-encoding filters.


But placing these your ideas in www.perlmonks.org the Meditations
section is proper place, which will be quickly commented with a very
high quality.

With best regards,
Vadim.


Johan Vromans

unread,
Nov 6, 2006, 4:22:54 AM11/6/06
to Chia-liang Kao, perl5-...@perl.org
Chia-liang Kao <cl...@bestpractical.com> writes:

> Basically what this does is create package variable "$self" for the
> caller during import.

To gain wide acceptance, you should provide an import method to use
"$this" or "$me" instead of "$self".

use selfless '$this';

-- Johan

Tatsuhiko Miyagawa

unread,
Nov 6, 2006, 5:18:44 AM11/6/06
to perl5-...@perl.org
On 05 Nov 2006 06:58:55 -0800, Randal L. Schwartz <mer...@stonehenge.com> wrote:
> The problem with this is that a package rarely has *only* methods.
> You need some way to say "this subroutine is a method" vs "that subroutine
> is being used as an ordinary subroutine".

Spiffy, which is a source filter, does this by checking if the fuction
is declared as 'sub function()'.

--
Tatsuhiko Miyagawa

Jerry D. Hedden

unread,
Nov 6, 2006, 10:30:21 AM11/6/06
to Chia-liang Kao, perl5-...@perl.org
Chia-liang Kao wrote:
> While discussing some evil today with Jesse, I went to
> make a proof of concept selfless.pm, which does
> "my $self = shift" for you.
>
> I know there are several implementations of this, which
> requires either source filter or deep magic. But this one
> is surprisingly clean to me, which seems too good to be
> true, so I wonder if I am missing something obvious. The
> only magic it needs is _forget_unlocal in Data::Bind.

>
> Basically what this does is create package variable
> "$self" for the caller during import. on init time, it
> walks the functions defined in the modules that wants
> selfless, and wrap them with local $self = shift,
> forget_unlock it for 1 level, and goto the original
> coderef. And this is not using lexwrap so we don't have
> the caller() runtime penalty.
>
> Attached is a quick implementation that segfaults randomly
> and doesn't collect the functions actually defined in the
> pacakge correctly. But if we can get the forget_unlocal
> semantics defined and supported, maybe we can have use
> features 'methods'.

This looks interesting, and I'm going to investigate adding
this as a feature to Object::InsideOut. However, the
implementation appears to me to be a bit more complicated
than it needs to be. Can't you do the same thing without
'local' and _forget_unlocal?

our @orz;

sub import {
no strict 'refs';
my $self = $caller.'::self';
${$self} = undef;
push @orz, $caller;
}

use Data::Bind ();
INIT {
no strict 'refs';

for my $caller (@orz) {
for (keys %{$caller.'::'}) {
my $code = $caller->can($_) or next;
next if $_ eq 'isa';
my $self = $caller.'::self';
*{$caller.'::'.$_} = sub {
${$self} = shift;
goto $code;
};
}
}
}


__________________________________________________________________________________________
Sponsored Link

Talk more and pay less. Vonage can save you up to $300 a year on your phone bill.
Sign up now. http://www.vonage.com/startsavingnow/

Chia-liang Kao

unread,
Nov 6, 2006, 10:39:34 AM11/6/06
to jdhe...@1979.usna.com, perl5-...@perl.org
於 一,2006-11-06 於 07:30 -0800,Jerry D. Hedden 提到:

> This looks interesting, and I'm going to investigate adding
> this as a feature to Object::InsideOut. However, the
> implementation appears to me to be a bit more complicated
> than it needs to be. Can't you do the same thing without
> 'local' and _forget_unlocal?

package Fnord;

sub foo {
$other_fnord_object->bar;
$self->baz; # what would happen to the $self here?

Chia-liang Kao

unread,
Nov 6, 2006, 10:58:24 AM11/6/06
to Vadim, perl5-...@perl.org
於 六,2006-11-04 於 20:19 +0300,Vadim 提到:

> I think this is just taking your gun directly to your foot.
> Perl allow this, but no doubt you *will* shoot the foot.
>
> Very dangerous concept.
> The sooner you'll refuse the better.
>
> If you need flexible OO approach, then go to perl6, which is better and
> better these days.

I don't know if you noticed Data::Bind, which I put the forget_unlocal
magic in, was born to support the Perl6 calling convention for the
6-on-5 stack.

Having written some perl6 and yet having to write perl5, I really want
something other than source filter to type obvious things for me, and
make me still enjoy using the language.

> all source filters are deprecated.
> Except simplies source-encoding filters.

That's why I was happy and surprised with the simple idea I had.

Cheers,
CLK


Jerry D. Hedden

unread,
Nov 6, 2006, 11:34:17 AM11/6/06
to Chia-liang Kao, perl5-...@perl.org
Chia-liang Kao wrote:
> The only magic it needs is forget_unlocal in Data::Bind.
>
> Attached is a quick implementation that segfaults randomly...

Why does it randomly segfault? Is it because the implementation of
_forget_unlocal is flawed?


____________________________________________________________________________________
Sponsored Link

Get an Online or Campus degree
Associate's, Bachelor's, or Master's - in less than one year.
http://www.findtherightschool.com

0 new messages