http://qs321.pair.com?node_id=728554

matija has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a project which uses TheSchwartz, and I saw that it was supposed to work with multiple databases.

I was not sure how it would maintain some of it's stuff over more than one database, so I tested it - and found that all the stuff kept going to the same database server.

I looked at the source, and found that it's routine for shuffling databases uses Util::List, and so I tested it:

perl -e 'use List::Util qw(shuffle); @a=[1,2,3,4,5,6,7,8,9,10]; foreac +h (1..24) { print join(",",@ { shuffle(@a) })."\n"}'
That gave me:
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,10
The shuffle routine in List::Util looks reasonable at first glance:
sub shuffle (@) { my @a=\(@_); my $n; my $i=@_; map { $n = rand($i--); (${$a[$n]}, $a[$n] = $a[$i])[0]; } @_; }
Personally, I'm never comfortable using floating point values for array indices, but perhaps there's a perl magic at work that I don't understand. At any rate, either there's a bug in shuffle, or something is very wrong with my random generator - or am I, along with the author of TheSchwartz using List::Util::shuffle incorrectly?

Replies are listed 'Best First'.
Re: Bug in List::Util::shuffle ?
by friedo (Prior) on Dec 06, 2008 at 14:50 UTC

    You're shuffling a one-element list containing an array reference, then dereferencing that. A one-element list has only one possible order.

    Try this instead:

    perl -e 'use List::Util qw(shuffle); @a=(1,2,3,4,5,6,7,8,9,10); foreac +h (1..24) { print join(",",shuffle(@a) )."\n"}'

      Aaaggghhh! You're right! I hate it when I do something stupid like that...
Re: Bug in List::Util::shuffle ?
by PetaMem (Priest) on Mar 23, 2009 at 08:58 UTC

    Well - maybe not a bug, but does anyone know the answer to the question in this thread 5 years ago?

    I asked myself the same question today. Unfortunately, the List::Util POD doesn't answer it, neither does the source or (lack of) remarks.

    It certainly doesn't look like the Fisher-Yates described in the Perl Cookbook on p. 121

    Bye
     PetaMem
        All Perl:   MT, NLP, NLU

      The implementation seems to be identical to the modern version of the Fisher-Yates shuffle, as found again by Richard Durstenfeld and published by Donald Knuth.