views:

71

answers:

1

I am trying to add new methods to an object dynamicaly.

Following code works just fine:

use SomeClass;

my $obj = SomeClass.new;
my $blah = 'ping';
my $coderef = method { say 'pong'; }

$obj.^add_method($blah, $coderef);

$obj.ping;

this prints "pong" as expected, whereas the following will not work as expected:

use SomeClass;

my $obj = SomeClass.new;
my %hash = one => 1, two => 2, three => 3;

for %hash.kv -> $k, $v {
    my $coderef = method { print $v; }
    $obj.^add_method($k, $coderef);
}

$obj.one;
$obj.two;
$obj.three;

will print either 111 or 333.

Could anyone explain to me what i am missing or why the results are different from what i was expecting?

+7  A: 

Rakudo had some issues with accidentally sharing lexical variables over-eagerly, which might have caused your problem (the code reference closes over $v). With the current development version of Rakudo (and thus in the next release, and in the "Rakudo Star" release too), this code works:

class SomeClass { };

my $obj = SomeClass.new;
my %hash = one => 1, two => 2, three => 3;

for %hash.kv -> $k, $v {
    my $coderef = method { say $v; }
    $obj.^add_method($k, $coderef);
}

$obj.one;
$obj.two;
$obj.three;

Output:

1
2
3

Note that whitespace between method name and parenthesis is not allowed.

moritz
thank you for this info. i used the latest monthly release.
mugen kenichi