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

Code
use strict; use warnings; my $ENABLE = 0; my $REQUIRE = 1; my $DISABLE = 2; my $DataRates = 'basic-2.0 1.0 basic-5.5'; my %DataRatesHash = (1.0 => $DISABLE, 2.0 => $DISABLE, 5.5 => $DISABL +E, 48.0 =>$DISABLE, 54.0=>$DISABLE); foreach my $rate (split(/ /, $DataRates)) { if(my ($rate1) = $rate =~/basic-(.+)/) { print "Data Rate - $rate \n"; %DataRatesHash->{$rate1} = $REQUIRE; print %DataRatesHash->{$rate1}; print "\n"; } else { print "Data Rate - $rate \n"; %DataRatesHash->{$rate} = $ENABLE; print %DataRatesHash->{$rate}; print "\n"; } } print %DataRatesHash->{2.0} ; print %DataRatesHash->{1.0} ; print %DataRatesHash->{5.5} ; print %DataRatesHash->{48.0} ;
My code prints the following results:
Results
Data Rate - basic-2.0 1 Data Rate - 1.0 0 Data Rate - basic-5.5 1 2212
I do not know why the changes that I have made to the hash values of keys 2.0 1.0 didn't take effect outside the loop
Expected Results
Data Rate - basic-2.0 1 Data Rate - 1.0 0 Data Rate - basic-5.5 1 1012 # Since I modified the hash inside the loop
I would appreciate if someone can point me the error.
Thanks!

2005-10-05 Retitled by planetscape, as per Monastery guidelines
Original title: 'What is wrong with my code?'

Replies are listed 'Best First'.
Re: hash, deref & looping problem
by pg (Canon) on Oct 04, 2005 at 23:12 UTC

    Just put quotes around your hash keys, to avoid convertion.

    use Data::Dumper; use strict; use warnings; my $ENABLE = 0; my $REQUIRE = 1; my $DISABLE = 2; my $DataRates = 'basic-2.0 1.0 basic-5.5'; my %DataRatesHash = ("1.0" => $DISABLE, "2.0" => $DISABLE, "5.5" => $ +DISABLE, "48.0" =>$DISABLE, "54.0"=>$DISABLE); print Dumper(\%DataRatesHash); foreach my $rate (split(/ /, $DataRates)) { if(my ($rate1) = $rate =~/basic-(.+)/) { print "Data Rate 1 - $rate \n"; print "rate1 = $rate1\n"; $DataRatesHash{$rate1} = $REQUIRE; print $DataRatesHash{$rate1}; print "\n"; } else { print "Data Rate 2 - $rate \n"; $DataRatesHash{$rate} = $ENABLE; print $DataRatesHash{$rate}; print "\n"; } } print Dumper(\%DataRatesHash); print $DataRatesHash{"2.0"} ; print $DataRatesHash{"1.0"} ; print $DataRatesHash{"5.5"} ; print $DataRatesHash{"48.0"} ;

      Just to expand slightly on pg's reply, perldoc perlop says

      The "=>" operator is a synonym for the comma, but forces any word (consisting entirely of word characters) to its left to be interpreted as a string (as of 5.001). If the argument on the left is not a word, it is first interpreted as an expression, and then the string value of that is used.

      And you would have gotten away with it, too, if it weren't for that meddling interpretation of non-words as expressions.

      Thanks to all who replied! I corrected the code as per your suggestion and now it works!
Re: hash, deref & looping problem
by davido (Cardinal) on Oct 04, 2005 at 23:21 UTC

    I downloaded that code and ran it as is, and got the following:

    Using a hash as a reference is deprecated at test.pl line 20. Using a hash as a reference is deprecated at test.pl line 21. Using a hash as a reference is deprecated at test.pl line 27. Using a hash as a reference is deprecated at test.pl line 28. Using a hash as a reference is deprecated at test.pl line 33. Using a hash as a reference is deprecated at test.pl line 34. Using a hash as a reference is deprecated at test.pl line 35. Using a hash as a reference is deprecated at test.pl line 36.

    The warnings about using a hash as a reference are from any line where you've got the following syntax: %hash_ref_name->{keyname}. That's because you're using the wrong sigil. It should be $hash_ref_name->{keyname} (note, the $ instead of the %). But you're also using a named hash, not a hashref, so you don't need the '->' operator. So the correct syntax is actually: $hashname{keyname}. Note the use of '$', and the absence of '->'.

    The next issue is the difference between your expected output and the actual output...First quote your keys so they don't get numerified.

    1. The first time through the loop, $rate contains "basic-2.0", so $DataRatesHash{2.0} is set to 1.
    2. The second time through the loop, $rate contains "1.0", so $DataRatesHash{1.0} is set to 0.
    3. The third time through the loop, $rate contains "basic-5.5", so $DataRatesHash{5.5} is set to 1.
    4. $DataRatesHash{48.0} remains unchanged at 2.

    So when you print @DataRatesHash{ '2.0', '1.0', '5.5', '48.0' } (please excuse the shorthand), you get the expected 1012.


    Dave

Re: hash, deref & looping problem
by GrandFather (Saint) on Oct 04, 2005 at 23:11 UTC

    Change all your %DataRatesHash->{} to $DataRatesHash{}.

    %DataRatesHash-> is dereferencing a hash which is probably not what you want.

    Update: Oops, look beyond the warnings to the actual result - you need to quote the numbers you are using as keys.


    Perl is Huffman encoded by design.

      That resolves the syntax warning, but it is not related to his issue.

      His issue is that, he thought there is a key "2.0" in his original hash, but there is not, there is a "2". Adding quotes to avoid convertion, should resolve that.