in reply to Hash shuffle help

#!/usr/bin/perl use strict; use Tie::File; use List::Util qw/shuffle/;

You should also include the warnings pragma (it would have warned you about one of the lines of your program.)

#!/usr/bin/perl use warnings; use strict; use Tie::File; use List::Util qw/shuffle/;


my $line; my $i=0; my @array; my $count=0; my $alphaFile = 'alphabetFile.txt'; my $numberFile = 'numberFile.txt'; my $fileCounter = 'counter.txt'; my $tempFile = 'temp.txt'; open(FILECOUNTER,$fileCounter); $count = <FILECOUNTER>; chomp($count);

Why are these lines in file scope?    They should be inside the subroutine.    You should also verify that open worked correctly.



&readfile();

There is no need to prepend an ampersand when using subroutine calls and it may cause unwanted side effects.



tie @array, 'Tie::File', $numberFile || die("failed to open $numbe +rFile");;

You should declare @array here where you first use it instead of at file scope.

You are using the high precedence || operator which means that you are testing the boolean value of $numberFile NOT the success or failure of tie.

tie my @array, 'Tie::File', $numberFile or die "failed to open $nu +mberFile";


if (-e $tempFile) { open(TEMPFILE,"+<$tempFile") || die("failed to open $tempFile" +);

There is no need to stat the file first, just let open do its job:

if ( open TEMPFILE, '+<', $tempFile ) {


my $counter=0;

You never use this variable anywhere??



tell(TEMPFILE);

You are using tell in void context so this line is superfluous.    (The warnings pragma would have warned you of this.)



while ($line = <CHARFILE>) {

You should declare $line here where you first use it instead of at file scope:

while ( my $line = <CHARFILE> ) {


if ("$line $array[$i]") {

This test is superfluous because the string "$line $array[$i]" is ALWAYS true.



foreach ( $line ) {

You are looping over a list with one element.    The foreach loop aliases $line to $_ but you are not using $_ inside the loop so it is superfluous.



print shuffle $array[$i] . "\n";

shuffle works on a list and returns a shuffled list but you are only passing shuffle a single element, the string "$array[$i]\n", so there is nothing really for shuffle to do, except return that one element.



print "\n" . $line . " " . rand "$array[$i]" . + "\n";

You have three problems there: 1) rand works with numbers but you are copying the contents of $array[$i] to a string, so perl has to convert that string to a number for rand to work, and: 2) because of the high precedence of the concatenation operator you are actually passing rand the string "$array[$i]\n" which means that: 3) the newline is not printed out as you may have expected.

That will work correctly if you use the comma operator instead:

print "\n", $line, " ", rand $array[ $i ], "\n +";


You should also include the $! in your error messages when using open so you know why it failed.

Replies are listed 'Best First'.
Re^2: Hash shuffle help
by Anonymous Monk on Nov 15, 2011 at 05:15 UTC
    There is no need to prepend an ampersand when using subroutine calls and it may cause unwanted side effects.

    FUD much? :)

    Just testing in Production. Sorry, it shouldn't have let me post this.