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

Pretty elementary problem, I'm sure, but:
#!/usr/bin/perl open(LANGUAGES,"languages.txt") || die "cannot open cities"; %lang_dev = <LANGUAGES>; $hard_reference = \%lang_dev; # \ creates reference to %lang_dev print "Enter a programming language: "; chomp($lang = <STDIN>); print "\n"; print "$lang was originally developed by $$hard_reference{$lang}.\n"; # "$" to dereference hash so value can be accessed sleep (3);
and languages.txt:

Perl, Larry Wall
Java, James Gosling
C, Dennis Ritchie
C++, Bjarne Stroustrup

produces (when entering Perl):

Perl was originally developed by .

Any insite? Thanks!

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: The following returns no value for $lang
by Fastolfe (Vicar) on Oct 26, 2000 at 22:28 UTC
    You aren't creating your %lang_dev hash correctly. If you want to break it apart by commas, you need to read each line, split on the comma, and store it:
    while (<LANGUAGES>) { chomp; my ($key, $value) = split /,\s*/; $lang_dev{$key} = $value; }
    Your method for pulling the data from a hash reference should be fine, but you might also consider writing it this way (which in my opinion is a bit more clear)

    Editor's note: This post originally included tekniko's question, properly formated. Since I added the formatting tags to the question, I removed the duplication from this post.

    Originally posted as a Categorized Answer.

Re: The following returns no value for $lang
by kilinrax (Deacon) on Oct 26, 2000 at 22:35 UTC
    You are using references unnecessarily; a hash would work just fine. I suspect what you probably want is something more like this:
    #!/usr/bin/perl -w use strict; open(LANGUAGES,"languages.txt") or die "cannot open languages.txt"; my $line; my %hash; foreach $line (<LANGUAGES>) { my ($language, $author) = split ', ', $line; $hash{$language} = $author; } my $lang; print "Enter a programming language: "; chomp ($lang = <STDIN>); if (exists $hash{$lang}) { print "$lang was originally developed by $hash{$lang}.\n"; } else { warn "Language not found!"; }

    Originally posted as a Categorized Answer.

Re: The following returns no value for $lang
by tedv (Pilgrim) on Oct 27, 2000 at 02:10 UTC
    If I saw this behavior, the first thing I'd look at would be the contents of your data hash. The data hash has clearly been set up improperly if the value is a null string-- most likely you're accessing keys that aren't actually in the hash. In particular, this is a great opportunity for the data dumper:
    use strict; use Data::Dumper; my %lang_dev; # ... print Dumper(\%lang_dev);

    Incidently, if you want to dereference a hash reference and lookup a key at the same time, it's cleaner to write $hash_ref->{$key} although it's the same as ${$hash_ref}{$key}.

    Watch out for the proper bracing with references though. The following code doesn't do what you think it does:
    my @foo = @$hash_ref->{$key}
    The @ will try to reference $hash_ref first, instead of decoding $hash_ref->{$key} into a reference-to-array. In such a situation, use braces to force context:
    my @foo = @{$hash_ref->{$key}}
    I only bring this up because the reference precedence rules have cause me heartache in the past. Is there a good formal rule for determining which decoding gets done when in situations like this? I just add extra braces when I don't know, but this could cause unnecessarily unreadable code.

    -Ted

    Originally posted as a Categorized Answer.