Search code examples
stringlistperl

Why are these values sometimes undefined?


I'm fairly new to Perl and am working on a project to further my learning. It's a little console word game (translated from a python project of mine), and part of the logic requires to draw a random letter from a pool that is 98 characters long.

Running the functions individually, I've never had an issue, but when I try to loop it into a list it occasionally fails. Running with warnings on tells me that some of these are undefined, but I can't for the life of me figure out why. Here's an MRE:

package Random;
sub choice {
  shift;
  my ($str) = @_;
  my $random_index = int(rand(length($str)));
  return substr($str,$random_index,1); #fixed variable name
}
package Player;
sub new {
  my $class = shift;
  my $self = { "name" => shift, "letters" => {fillList()} };
  bless $self, $class;
  return $self;
}
sub drawCharacter {
  my $freq = "aaaaaaaaabbccddddeeeeeeeeeeeeffggghhiiiiiiiiijkllllmmnnnnnnooooooooppqrrrrrrssssttttttuuuuvvwwxyyz";
  my $choice = Random -> choice($freq);
  return $choice;
}
sub fillList {
  my @ls = ();
  for (0..6) {
    push @ls, drawCharacter();
  }
  return @ls;
}
sub getLetters {
  my ($self) = @_;
  my $arr = $self -> {letters};
  return %$arr;
}


package Main;
my @players = ();
for (0..12){
  my $player = Player -> new("Foo");
  print($player->getLetters(),"\n");
}

BIG EDIT: Adding the object I'm using. This is verifiably not working. Warnings: "Use of uninitialized value in print" and "Odd number of elements in anonymous hash". This is where I think the issue lies.

The list returned by fillList sometimes is missing an item or 2, and in some circumstances even 3 or 4 items are missing. Does anybody know what's going on here? The python one hasn't failed once.

If the python analogue would be helpful, I can include that here too.


Solution

  • The error comes from using a hash ref where you should have an array ref:

    my $self = { "name" => shift, "letters" => {fillList()} };
    #                                          ^          ^-- wrong brackets
    

    This is what the warning talks about:

    Odd number of elements in anonymous hash at foo.pl line 22.
    

    You want to change that to:

    my $self = { "name" => shift, "letters" => [fillList()] };
    #                                          ^          ^--- creates array ref
    

    And also the line which uses this array

    return %$arr;
    

    Where you need to change % to @.

    return @$arr;
    

    After those fixes, the code runs without errors for me.