When I wrote Hangman in Perl 6, I used the following for shuffling a list:
my method shuffle (*@items) { # Fisher-Yates shuffle my $i = @items.elems; while ($i) { my $j = $i.rand.int; $i--; @items[ $i, $j ] = @items[ $j, $i ]; } return @items; }
Today I was bothered by this and realized that it's not very Perl 6ish. In fact, Perl 6 is so focused on solving common programmer problems that I realized that the List class should have a shuffle builtin. After much playing around in the internals of Perl 6 and attempting to implement the Fisher-Yates shuffle, I realized that the pick method was better, so I was going to implement it internally with pick, but then I read the documentation more carefully. Shuffling an array in Perl 6 is trivial; the name is just not what I expected.
my @shuffled = @array.pick(*);
@array.=pick(*);
This might even be optimized and actually shuffle the elements within the array.
Re:Overwriting the array in place
Ovid on 2009-01-12T21:01:19
Yeah, I'm discovering that as I'm writing tests for my $string.trim function (and it looks like it will be accepted as part of core Perl 6! Yay!
:) Re:Overwriting the array in place
afbach on 2009-01-20T23:20:12
Trying that in the hangman code:
@items.=pick(*);gets:
Null PMC access in find_method()if I do either (after:
my $i = @items.elems;
):
@items.=pick($i);or:
@items = @items.pick($i);I get:
Cannot assign to readonly variableDoing:
return @items.pick($i);works though ('*' again gets the Null PMC).
Re:Overwriting the array in place
Ovid on 2009-01-21T11:12:40
That pick seems to work for me:
~ $ perl6 -e 'my @items = ^10; @items
.= pick(*); @items.perl.say'
[2, 8, 9, 4, 1, 5, 3, 7, 6, 0]
~ $ perl6 -e 'my @items = ^10; my $i = @items.elems; @items.= pick(*); @items.perl.say'
[6, 2, 7, 1, 4, 8, 9, 5, 3, 0]
~ $ perl6 -e 'my @items = ^10; my $i = @items.elems; @items.= pick($i); @items.perl.say'
[7, 8, 5, 1, 2, 0, 4, 3, 9, 6]
~ $ perl6 -v
This is Rakudo Perl 6, revision 35858 built on parrot 0.9.0-devel
for darwin-2level.
Copyright 2006-2008, The Perl Foundation.If you update parrot and can produce a small test case, I'd be curious to see it. Or I just might be misunderstanding you
:) Re:Overwriting the array in place
afbach on 2009-01-21T16:35:11
Yeah, I was able to get it to work from the command line yesterday too, so I'm guessing it's got to do w/ @items being a param to a method, maybe?, as in hangman.pl. Just try your new shuffle in there. I was working on making up a smaller test case. I use a nightly fetch of parrot/rakudo.Re:Overwriting the array in place
afbach on 2009-01-24T19:17:54
Good news! as of Rakudo Perl 6, revision 35960 built on parrot 0.9.0-devel:
return @items.pick(*);works, at least on x86 Leopard box.