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

Hi monks, I am studying the references on perlreftul. It showed an example of using references to a hash containing countries and cities(http://perldoc.perl.org/perlreftut.html). I created a test file containing the country city list,
Chicago, USA Frankfurt, Germany Berlin, Germany Washington, USA Helsinki, Finland New York, USA
then test the code as below:
#!/usr/bin/perl -w use strict; my %table; while (<>){ chomp; my ($city,$country)=split/,/; $table{$country}=[] unless exists $table{$country}; push @{$table{$country}}, $city; } my $a=$table{"USA"}; print $a; #line 12 foreach my $country (sort keys %table){ if ($country eq "USA"){ print "USA is found\n"; } else{} }
Wierd thing happend. first, I can not print the element of $table{"USA"}, giving the error "Use of uninitialized value in print at country_city.pl line 12, <> line 6.". Second, the foreach loop can not find $country equals to "USA", thus, it can not print "USA is found", it just printed nothing. What happened? This really confused me. Thanks.

Replies are listed 'Best First'.
Re: Can not print hash element
by dreadpiratepeter (Priest) on Sep 23, 2008 at 01:49 UTC
    You have not taken the spaces in your input into account. try:
    split /\s*,\s*/;
    that should fix it.
    You were generating a key of " USA", not "USA".


    -pete
    "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
      Thank you very much. You have sharp eyes. It's fixed.
        Another opportunity to promote Data::Dumper =)
        use Data::Dumper; local $Data::Dumper::Useqq = 1; # print non-printable chars print Dumper \%table;

        So, whenever perl seems to be wrong, first debug yourself what data you have.
Re: Can not print hash element
by lamp (Chaplain) on Sep 23, 2008 at 02:05 UTC
    use Data::Dumper module for debugging these kind of issues. The following is the output of '%table' hash using Data::Dumper before removing the space from your input. You can find spaces in front of all the country names.
    use Data::Dumper; print Dumper(%table);
    output
    $VAR1 = ' Germany'; $VAR2 = [ 'Frankfurt', 'Berlin' ]; $VAR3 = ' Finland'; $VAR4 = [ 'Helsinki' ]; $VAR5 = ' USA'; $VAR6 = [ 'Chicago', 'Washington', 'New York' ];
Re: Can not print hash element
by poolpi (Hermit) on Sep 23, 2008 at 10:43 UTC

    Skipping duplicate cities and regexp

    #!/usr/bin/perl -w use strict; use Data::Dumper; my $country; # Hash ref ;) my $sep = q{,}; while (<DATA>) { chomp; next if /\A\z/; /\s* (.+) \s* $sep \s* (.+) \s*/msx; next unless defined $1 and defined $2; grep { /$1/i } @{ $country->{$2} } or push @{ $country->{$2} }, $1; } print Dumper $country; __DATA__ Chicago, USA Frankfurt, Germany Berlin, Germany Washington, USA Helsinki, Finland Berlin, Germany New York, USA Freetown, Sierra Leone

    hth,
    PooLpi

    'Ebry haffa hoe hab im tik a bush'. Jamaican proverb