in reply to Re^6: csv to hash table
in thread csv to hash table

The syntax for accessing values in a hash via a hash variable is different from the syntax for access values in a hash via a reference to a hash variable. You are using the one where you should be using the other, thus you are getting an error.

To access a value in a hash via a hash variable, you can use the following syntax:

my $value = $hash{$key};

To access a value in a hash via a reference to a hash variable, you can use the following syntax:

my $value = $hash_ref->{$key};

The -> in this second example dereferences the hash ref.

You have a hash variable (%hash) and a reference to a hash variable ($hash_ref). You don't need the latter, but you can use it if you want to. In fact, you declare $hash_ref and set it to a reference to %hash, but you don't use it anywhere, so you can simply remove it. It makes no difference in the code you posted.

The first line you marked with "++++ Error ++++" includes: $hash->{$key_CSV}. Because $hash is followed by ->, $hash must be a scalar containing a reference, but you don't have such a variable defined in the code you have posted.

If you change that bit to $hash{$key_CSV}, then you will be accessing the value from %hash which you have declared and initialized.

At the second line marked with "++++ Error ++++", you have $hash. This is a scalar variable but in the code you posted it is not declared or initialized. While $hash{$key} accesses a value in the hash %hash, $hash does not refer to %hash at all, it refers to the scalar with a similar name.

The ability to use the same "name" to refer to different variables can be a confusing aspect of Perl. Remember that $name, @name and %name are three different variables: changes to one do not affect the others. It can be more confusing that $name{$key} accesses %name rather than $name, but that's the way it is.

There are many ways you could change the subroutine you posted to eliminate the errors. Here are a couple of simple changes for you to consider:

sub mainCSV { # Open the CSV input file open (my $infile_CSV1, '<', "$infile_CSV") or die "Unable to open $infile_CSV: $!\n"; my %hash = (); while (my $line = <$infile_CSV1>) { chomp; $line =~ s/\s*\z//; my @array_CSV = split /,/, $line; my $key_CSV = shift @array_CSV; push @{ $hash{$key_CSV} }, $_ foreach @array_CSV; print Data::Dumper->Dump([ \@array_CSV, \%hash], ["array_CSV", + "hash"] ); } # Explicit scalar context my $size = scalar keys %hash; }

Or

sub mainCSV { # Open the CSV input file open (my $infile_CSV1, '<', "$infile_CSV") or die "Unable to open $infile_CSV: $!\n"; my %hash = (); my $hash_ref = \%hash; while (my $line = <$infile_CSV1>) { chomp; $line =~ s/\s*\z//; my @array_CSV = split /,/, $line; my $key_CSV = shift @array_CSV; push @{ $hash_ref->{$key_CSV} }, $_ foreach @array_CSV; print Data::Dumper->Dump([ \@array_CSV, $hash_ref], ["array_CS +V", "hash_ref"] ); } # Explicit scalar context my $size = scalar keys %hash; }

And if you really want to do it the second way, you can simplify that to:

sub mainCSV { # Open the CSV input file open (my $infile_CSV1, '<', "$infile_CSV") or die "Unable to open $infile_CSV: $!\n"; my $hash_ref = {}; while (my $line = <$infile_CSV1>) { chomp; $line =~ s/\s*\z//; my @array_CSV = split /,/, $line; my $key_CSV = shift @array_CSV; push @{ $hash_ref->{$key_CSV} }, $_ foreach @array_CSV; print Data::Dumper->Dump([ \@array_CSV, $hash_ref], ["array_CS +V", "hash_ref"] ); } # Explicit scalar context my $size = scalar keys %$hash_ref; }