1

I'm trying to generate a list of hashes, interacting with the user using the following script:

use strict;
use warnings;

my $KEY_1 = "one";
my $KEY_2 = "two";


sub generateHash{
    my ($value1, $value2) = (@_);

    $value2 = $value1 + 5.0;

    my %hash = {};

    $hash{$KEY_1} = $value1;
    $hash{$KEY_2} = $value2;

    return %hash;
}

print "Num: \n";
my $number = <>;

my @hashes = ();
my %new_hash = {};

for ( my $i = 1; $i < $number + 1; $i = $i + 1 ) {

    print "Enter the values  $i \n";

    print "value 1: ";
    my $value1= <>;

    print "\nvalue 2: ";
    my $value2= <>;

    chomp $value1;
    chomp $value2;

    %new_hash = generateHash($value1, $value2);     

    push (@hashes, %new_hash);
    print "@hashes\n";
}

my %test = $hashes[0];
my @keys = keys %test;
my @values = values %test;

print "@keys\n";
print "@values\n";

When I try to execute the program, it raises some errors related to use of references when accessing to the hashes within the array. I'm missing something but I can't see what, I wonder where I'm accessing to hash's reference. Thank you in advance, attached is the output from the execution:

Num: 
1
Reference found where even-sized list expected at generate_hashes.pl line 21, <> line 1.
Enter the values  1 
value 1: 1

value 2: 1
Reference found where even-sized list expected at generate_hashes.pl line 12, <> line 3.
Use of uninitialized value $hashes[1] in join or string at generate_hashes.pl line 32, <> line 3.
HASH(0x2587a88)  one 1 two 6
Odd number of elements in hash assignment at generate_hashes.pl line 34, <> line 3.
HASH(0x2587a88)
Use of uninitialized value $values[0] in join or string at generate_hashes.pl line 38, <> line 3.
Borodin
  • 123,915
  • 9
  • 66
  • 138
Hellzzar
  • 165
  • 8

1 Answers1

2

Reference found where even-sized list expected at generate_hashes.pl line 21, <> line 1.

That one is due to

my %new_hash = {};

Empty curly braces {} provide a reference to an empty hash, but on the left hand side you have a hash, not a reference to one. You could instead initialise using:

my %new_hash = ();

But (as commented) you don't in practice need to initialise if you want to start with an empty hash; that's the default.

Reference found where even-sized list expected at generate_hashes.pl line 12, <> line 3.

Same fault as above inside the generateHash function.

In this line:

push (@hashes, %new_hash);

I suspect you intend to push a reference to the hash into the array, to do that you need to add a \:

push( @hashes, \%new_hash );

Otherwise you'll be putting the whole data structure in the array, etc.

In this line:

my %test = $hashes[0];

Your right-hand side is a scalar, a reference to a hash, hence you need to dereference to use that hash in the assignment:

my %test = %{$hashes[0]};

Messages like

HASH(0x2587a88)

Come from this line:

print "@hashes\n";

Not sure what you're intention is there, but you need to iterate over the data structure if you want to see the content (it'll be an array of references to hashes). You might consider using the Data::Dumper module to help you see the content there.

martin clayton
  • 72,583
  • 29
  • 209
  • 194
  • 1
    `my @foo = (); my %bar = ();` is redundant. You can just write `my @foo; my %bar;` instead. – melpomene May 06 '17 at 12:09
  • Thank you very much, it works now. Didn't realize I was initializing a reference with the braces. I see things clearer now :) and thanks for suggesting the use of Dumper. – Hellzzar May 06 '17 at 12:49