Delegation With 'handles'

On the train over to Stockholm after the hackathon and on the plane back to Spain a day later, I implemented various cases of 'handles' (not all of them, since the wildcard ones are trickier - they will get done probably along with a whole load of other work on attributes that needs doing). The 'handles' trait verb is the thingy that lets you auto-generate methods that delegate to a methods on an attribute. Here's some examples of what you can do with this:

class Bar { method a { say "a" }; method b { say "b" } }
class Foo1 { has $x handles 'a' } # one method
my $test = Foo1.new(x => Bar.new()); $test.a()
a
class Foo2 { has $x handles <a b> } # several
my $test = Foo2.new(x => Bar.new()); $test.a(); $test.b()
a
b
class Foo3 { has $x handles :mya('a') } # rename one
my $test = Foo3.new(x => Bar.new()); $test.mya();
a
class Foo4 { has $x handles (:mya('a'), :myb('b')) } # rename many
my $test = Foo4.new(x => Bar.new()); $test.mya(); $test.myb();
a
b

So, that's another small piece of the Perl 6 implementation puzzle put into place.

Categories:

0 TrackBacks

Listed below are links to blogs that reference this entry: Delegation With 'handles'.

TrackBack URL for this entry: http://www.rakudo.org/cgi-bin/mt/mt-tb.cgi/386

4 Comments

Dave Whipp Author Profile Page said:

is it correct that value of "handles" is a string -- should it be a method signature (e.g. to handle a(Int) but not a(Str))?

It's correct insofar as, "that's what the spec says". :-) I think the spec is correct too, though. All that 'handles' is doing is creating a kind of "forwarding" method in the current class that invokes that method on the attribute it is attached to. Any signature checking will then be done by the original method, which we have delegated to. It's possible that the method you are delegating to is a multi method too.



Hope this makes some sense.

bbkr Author Profile Page said:

The example below doesn't work as expected:

-------- 8

#!/usr/bin/perl

class A {

method p {
say 'A::p';
}

method q {
say 'A::q';
}

};

class B {

method p {
say 'B::p';
}

};

class T {

has $x handles 'q';
has $y handles 'p';

}

my $t = T.new(x => A.new(), y => B.new());

$t.p();$t.q();

-------- 8

expected output:

B::p
A::q

got:

Method 'p' not found for invocant of class 'Undef'
current instr.: 'parrot;T;p' pc 191 (EVAL_12:68)
called from Sub '_block10' pc 120 (EVAL_12:33)
called from Sub 'parrot;PCT::HLLCompiler;eval' pc 785 (src/PCT/HLLCompiler.pir:458)
called from Sub 'parrot;PCT::HLLCompiler;evalfiles' pc 1067 (src/PCT/HLLCompiler.pir:587)
called from Sub 'parrot;PCT::HLLCompiler;command_line' pc 1246 (src/PCT/HLLCompiler.pir:676)
called from Sub 'parrot;Perl6::Compiler;main' pc 8860 (perl6.pir:183)

am i doing sth wrong in example?

Your example is valid Perl 6, but the parsing of fatarrows (=>) isn't working properly in Rakudo just yet. Please use colonpair form for now. Changing this line:

my $t = T.new(x => A.new(), y => B.new());

To this:

my $t = T.new(:x(A.new()), :y(B.new()));

Makes your example work for me.

Thanks!

Jonathan

Leave a comment

About this Entry

This page contains a single entry by Jonathan Worthington published on April 9, 2008 11:51 PM.

Rakudo Gets Type Annotations And Checking was the previous entry in this blog.

Perl 6 Design Minutes for 09 April 2008 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Subscribe

    Subscribe to rakudo.org

Powered by Movable Type 4.1
Technorati Profile