Look Mom, No Source Filter!

chromatic on 2006-04-12T23:04:05

One of my favorite hacks in Perl Hacks shows how to declare the :Method attribute so you don't have to type my $self = shift; anymore. There are lots of ways to do that, but my approach was to avoid source filters (yay). The book goes into more detail, but effectively the trick allows you to declare any other parameter while avoiding most drawbacks of source filters.

Damian correctly pointed out that my technique does have the limitation of not always respecting the lexical compiling environment of the methods.

Today I figured out another approach that only handles invocants, but is strict safe. That is, now you can write:

package Foo;

use Attribute::Method;

sub new
{
    my ($class, %args) = @_;
    bless \%args, $class;
}

sub foo :Method
{
    return self->{foo}
}

Of course, you can also use this or o or just about any other allowed identifier.

What's the trick? I originally thought @DB::args would work, but if you take something off of the stack, it's just gone and so the really clever trampoline trick wouldn't do it. Now it only works with versions of Scalar::Util released this millennium.

Still, I don't really mind that syntax at all.


Table of Contents?

mdiep on 2006-04-12T23:59:36

It'd be nice if there was a table of contents on the Perl Hacks page -- even a tentative one. The rough cuts version would be much more enticing if I knew exactly what was in the book. :-)

Benchmarks using this method?

Alias on 2006-04-13T02:58:09

What sort of time penalty is this sort of technique going to introduce?

function calls are already pretty expensive, but depending on how you are implementing this I imagine it could result in a lot more of them. Would this be correct?

Re:Benchmarks using this method?

n1vux on 2006-04-13T15:06:23

Efficient, safe (no source filter) and concise may be too much to hope for, but would be wonderful. Requiring a Scalar::Util from this millenium seems fair.

Re:Benchmarks using this method?

chromatic on 2006-04-13T15:56:12

You are correct. It's as fast as it can be without a source filter and without using XS (though I can already think of a way to make it faster with XS).

:Method

phaylon on 2006-04-14T10:32:51

I have a little module that does exactly that for a little while now and didn't think anyone else was that crazy :)

I played the game even a bit more in the last weeks:

    sub foo :Method( Int $foo, Object $bar! ) {
            self->baz();
            print class, ': ', args->foo;
    }

Called via:

    $object->foo( foo => 23, bar => $bar_obj );

"args" returns just a container object, that uses autoload to simulate accessors. That's just to capture typos. It's mostly following the Perl 6 signature idea (at least the current one).

One problem is that it just can do positional or named arguments, not mixed:

    sub snafu :PosMethod( $foo, $bar ) {
          print args->foo, args->bar;
    } ...
    $object->snafu( 1, 2 );

Thanks to the Alias module it's also possible to do a :Method( Int $foo is rw ) and use the args call to change the original value. Everything else is just a copy, of course. Haven't gotten Readonly right til now.

Re::Method

blazar on 2006-11-19T14:25:43

"args" returns just a container object, that uses autoload to simulate accessors. That's just to capture typos. It's mostly following the Perl 6 signature idea (at least the current one).

Hmmm, it may pair nicely with Moose: although the latter claims not to be a Perl 6 implementation in Perl 5, it is admittedly heavily inspired by Perl 6 itself, and to some extent imports Perl 6 semantics, with special emphasis on OO features, in Perl 5. Also, it seems that unlike e.g. v6, it is much less experimental and much more production ready. Whatever, I seem to understand that there are potentially several projects you may want to attach or contribute to.

CPAN It?

Theory on 2006-06-12T18:02:48

Heya c, do you plan to release Attribute::Method on CPAN? I'd love to see it there, esp. if you have an XS implementation to do the magic lickedy-split!

—Theory

Re:CPAN It?

chromatic on 2006-06-12T20:24:17

Good idea. Keep bugging me about it; I don't have time in the next couple of weeks, but I'll experiment with the XS version.

Re:CPAN It?

Theory on 2006-06-12T21:09:59

Well surely you can get the pure Perl version out in the meantime, eh?

—Theory

Re:CPAN It?

Aristotle on 2006-12-02T20:27:12

*bug* *bug*