On Sat, Sep 20, 2008 at 12:46:53PM +0800, Chris Davaz wrote:
> In any-str.pir we need to figure out how to change
> .sub 'split' :method :multi('String')
> into
> .sub 'split' :method :multi(_, 'String')
> [...]
... let's back up a bit and look at what is really happening.
> [...] Any when we change ".sub 'split' :method :multi('String')"
> to ".sub 'split' :method :multi(_, 'String')" I can't even compile
> Perl 6. I get the following error:
> No applicable methods.
> current instr.: 'parrot;Perl6;Grammar;Actions;dec_number' pc 129924
> (src/gen_actions.pir:11299)
This isn't precise -- perl6.pbc compiles just fine. What isn't
compiling is Test.pm, because the dec_number method in actions.pm
is using the 'split' builtin to get rid of underscores (added in r31225):
method dec_number($/) {
my $num := ~$/;
$num := $num.split('_').join('');
make PAST::Val.new( :value( $num ), :returns('Num'), :node( $/ ) );
}
Here we're calling a Perl 6 builtin function from NQP, and NQP
doesn't convert string constants (such as '_') into String PMCs
prior to calling the function -- it just generates a PIR method
call directly. Unfortunately, Parrot doesn't recognize a string
constant as being the same as a 'String' for MMD purposes, and
so it's unable to match the split method declared :multi(_, 'String').
(This is arguably a Parrot bug, either in design or implementation.)
The solution to the problem is to define the method to split
on strings as :multi(_, _) -- i.e.:
.namespace ['Any']
.sub 'split' :method :multi(_, _)
This means this method will be used whenever there's not a more
specific multimethod available. Furthermore, this is actually
the correct semantics -- i.e., we expect the following to work
even though $x is an Int and not a Str:
my $x = 9;
say 439123912.split($x).perl; # [ "43", "123", "12" ]
So, try changing :multi('String') to :multi(_,_) and everything
should work just fine (and we should get a few more passing tests
to boot).
Pm