[kw-pm] Problem with hash
Eric Maki
eric at uc.org
Wed Jul 29 13:15:39 PDT 2009
> because you are 'use strict;'ing, soft references are allowed,
I meant because you are not 'use strict;'ing
See perldoc strict "strict refs" for a discussion of symbolic
references.
---- original message : 2009-07-29 4:09pm : Eric Maki ----
>
> If you are curious about what Perl thinks you want it to do, toss
>
> print Dumper \%text;
>
> at the end of your program:
>
> $VAR1 = {
> 'SYSTEM' => 'TEXT'
> };
>
> This is because:
>
> $prodFnd{"101010"}{"S0"} = "text";
>
> and then
>
> $prodFnd{"101010"}{"S0"}{"SYSTEM"} = "TEXT";
>
> because you are 'use strict;'ing, soft references are allowed, so
>
> $prodFnd{"101010"}{"S0"}{"SYSTEM"} = "TEXT";
>
> means
>
> $text{"SYSTEM"} = "TEXT";
>
> So, you just created a hash named %text and assigned to it.
>
> use strict 'refs'; was introduced because that behaviour is very frequently
> not what you want.
>
> Eric
>
>
> ---- original message : 2009-07-29 3:52pm : abez ----
>
>> Perl is doing exactly what you told it to do. The problem is that you
>> made a mistake and you didn't your code carefully enough to see it.
>>
>> do you see how you're testing {"SYSTEM"}, that's a key in "S0"'s hash.
>>
>> Except you assigned "S0" to a scalar.
>>
>> you're actually trying to overwrite a scalar with a hash that looks like
>> this:
>>
>> {
>> SYSTEM => "TEXT"
>> }
>>
>> when you go $prodFnd{$a}{$b}{SYSTEM} = $c;
>> you really mean is
>>
>> $prodFnd{$a}->{$b}->{SYSTEM} = $c;
>>
>> but $prodFnd{$a}->{$b} is not hash/hashref!
>>
>> You made $prodFnd{$a}->{$b} be "text";
>> not { SYSTEM => "text" }. There's a difference.
>>
>> Perl is auto-vivifying your hash. It brings it to life, it generates new
>> hashes.
>>
>> Just run this and you'll see that your initial assignments are to things
>> you're not even looking for. Step through it. Look at it. You don't even
>> have the same strings.
>>
>> use Data::Dumper;
>> $prodFnd{"101010"}{"S0"} = "text";
>> $prodFnd{"101010USED"}{"S0"} = "text";
>> print Dumper(\%prodFnd); #Do you see "SYSTEM" anywhere? No!
>> if (!exists($prodFnd{"101010"}{"S0"}{"SYSTEM"})) {
>> $prodFnd{"101010"}{"S0"}{"SYSTEM"} = "TEXT";
>> print "First<br>";
>> print Dumper(\%prodFnd); #you see "SYSTEM" now? No!
>> }
>> if (!exists($prodFnd{"101010USED"}{"S0"}{"SYSTEM"})) {
>> $prodFnd{"101010USED"}{"S0"}{"SYSTEM"} = "TEXT";
>> print "Second<br>";
>> print Dumper(\%prodFnd); #you see "SYSTEM" now? No!
>> }
>>
>> Then run
>> use strict;
>> use Data::Dumper;
>> $prodFnd{"101010"}{"S0"} = "text";
>> $prodFnd{"101010USED"}{"S0"} = "text";
>> print Dumper(\%prodFnd);
>> if (!exists($prodFnd{"101010"}{"S0"}{"SYSTEM"})) {
>> $prodFnd{"101010"}{"S0"}{"SYSTEM"} = "TEXT";
>> print "First<br>";
>> print Dumper(\%prodFnd);
>> }
>> if (!exists($prodFnd{"101010USED"}{"S0"}{"SYSTEM"})) {
>> $prodFnd{"101010USED"}{"S0"}{"SYSTEM"} = "TEXT";
>> print "Second<br>";
>> print Dumper(\%prodFnd);
>> }
>>
>> See all those warnings and errors? Fix those!
>>
>> If you had "use strict;" like recommended this would never have run
>> anyways because "S0" would not be a hash so you couldn't ask it for values.
>>
>> Summary: Hashes are not scalars, scalars are not hashes, use strict
>>
>> For more help, type:
>> perldoc perldata
>> and
>> perldoc -f exists
>>
>> Or go google for perldoc perldata.
>>
>> abram
>>
>>
>>
>> Robert Pike wrote:
>>> Sorry. I actually changed the name of the variables because of the data
>>> and such used (sensitive and such). I've simplified the problem I'm having
>>> below using the actual data retrieved from the array I'm using in this
>>> test.
>>>
>>> $prodFnd{"101010"}{"S0"} = "text";
>>> $prodFnd{"101010USED"}{"S0"} = "text";
>>> if (!exists($prodFnd{"101010"}{"S0"}{"SYSTEM"})) {
>>> $prodFnd{"101010"}{"S0"}{"SYSTEM"} = "TEXT";
>>> print "First<br>";
>>> }
>>> if (!exists($prodFnd{"101010USED"}{"S0"}{"SYSTEM"})) {
>>> $prodFnd{"101010USED"}{"S0"}{"SYSTEM"} = "TEXT";
>>> print "Second<br>";
>>> }
>>>
>>> This will only print First. I had also tried defined to see what I got and
>>> the same thing occured. I tried changing 101010USED to something else in
>>> the second if and it passed, changed only S0 to something else and it
>>> passed, and the same with SYSTEM and it passed. What am I missing? Thank
>>> you so much for the response and help as well. I also tried the data dump
>>> and it gave me what I expected. If I printed out what was in
>>> $prodFnd{"101010USED"}{"S0"}{"SYSTEM"} after the first if block it would
>>> actually print "TEXT". Does Perl ignore the letters after it sees letters
>>> in the first level of the hash or something?
>>>
>>>
>>>
>>> --- On Wed, 7/29/09, abez <abez at abez.ca> wrote:
>>>
>>>> From: abez <abez at abez.ca>
>>>> Subject: Re: [kw-pm] Problem with hash
>>>> To: "Robert Pike" <roberthpike at yahoo.com>
>>>> Cc: "KW Perl Mongers" <kw-pm at pm.org>
>>>> Received: Wednesday, July 29, 2009, 2:52 PM
>>>>
>>>> This doesn't parse:
>>>>
>>>>> for (my $cC=0$cC<=$#aA;$cC++) {
>>>> Space everything out, I think you're missing a semi-colon
>>>>
>>>> for ( my $cC = 0 ; $cC <= $#aA ; $cC++ ) {
>>>>
>>>> put use strict; up at the top. It'll tell you that vHash !=
>>>> vHsh
>>>> (misspelling).
>>>>
>>>> Then add a:
>>>>
>>>> use Data::Dumper;
>>>> print Dumper(\%vHsh);
>>>>
>>>> at the end of your program and you'll see the hash it
>>>> makes.
>>>> You'll notice you're checking for SS0 and S0 because you
>>>> have this
>>>> "S".$item2 everywhere.
>>>>
>>>> As well you're checking for $vHsh{$itm1}{$itm2}{"SYSTEM"}
>>>> but in your
>>>> examples you never set "SYSTEM", you in fact set
>>>> $vHsh{$itm1}{$itm2} to
>>>> a scalar value, not a hashref
>>>>
>>>> "use strict;" will attempt to spell check your variables. I
>>>> recommend
>>>> always using it.
>>>>
>>>> I've attached my code at the end of this message.
>>>>
>>>> abram
>>>>
>>>>
>>>> Robert Pike wrote:
>>>>> First off, thanks to all that supplied me with
>>>> feedback in regards to the issue I was having with
>>>> redirection in perl.
>>>>> I loop through an array, split the values, and put
>>>> certain values in a hash. Hopefully this will be enough info
>>>> to get some feedback.
>>>>> my %vHash;
>>>>> $vHsh{"101010"}{"S0"} = "text";
>>>>> $vHsh{"101010USED"}{"S0"} = "text";
>>>>>
>>>>> my @aA = ("101010~S0", "101010USED~S0");
>>>>> #if I were to do this
>>>>> for (my $cC=0$cC<=$#aA;$cC++) {
>>>>> ($itm1, $itm2) =
>>>> split(/\~/,$aA[$cC]);
>>>>> if
>>>> (!exists($vHsh{$itm1}{"S".$itm2}{"SYSTEM"})) { #--- also
>>>> tried defined
>>>>>
>>>> $vHsh{$itm1}{"S".$itm2}{"SYSTEM"} =
>>>> "TEXT";
>>>>> }
>>>>> }
>>>>>
>>>>> The if statement (with the
>>>> defined/exists check) criteria passes first pass but fails
>>>> in the second. Can anyone tell me why?
>>>>>
>>>>>
>>>> __________________________________________________________________
>>>>> Connect with friends from any web browser - no
>>>> download required. Try the new Yahoo! Canada Messenger for
>>>> the Web BETA at http://ca.messenger.yahoo.com/webmessengerpromo.php
>>>>> _______________________________________________
>>>>> kw-pm mailing list
>>>>> kw-pm at pm.org
>>>>> http://mail.pm.org/mailman/listinfo/kw-pm
>>>> use strict;
>>>> use Data::Dumper;
>>>> { #make a new scope
>>>> # this version does not work properly
>>>> # this is a minor modification to the original
>>>> version
>>>> my %vHsh;
>>>> $vHsh{"101010"}{"S0"} = "text";
>>>> $vHsh{"101010USED"}{"S0"} = "text";
>>>>
>>>> my @aA = ("101010~S0", "101010USED~S0");
>>>> #if I were to do this
>>>> my ($itm1, $itm2); #satisfy use strict
>>>> for (my $cC=0;$cC<=$#aA;$cC++) {
>>>> ($itm1, $itm2) =
>>>> split(/\~/,$aA[$cC]);
>>>> if
>>>> (!exists($vHsh{$itm1}{"S".$itm2}{"SYSTEM"})) { #--- also
>>>> tried
>>>> defined
>>>> warn "Found [$itm1 $itm2]";
>>>>
>>>> $vHsh{$itm1}{"S".$itm2}{"SYSTEM"} = "TEXT";
>>>> }
>>>> }
>>>> print Dumper(\%vHsh);
>>>> }
>>>>
>>>> print "$/ Now again but correctly $/";
>>>> {
>>>> # this is the new verison
>>>> my %vHsh;
>>>> $vHsh{"101010"}{"S0"}{"SYSTEM"} = "TEXT";
>>>> $vHsh{"101010USED"}{"S0"}{"SYSTEM"} = "TEXT";
>>>>
>>>> my @aA = ("101010~S0", "101010USED~S0");
>>>> #if I were to do this
>>>> for ( my $cC = 0 ; $cC <= $#aA ; $cC++ ) {
>>>> my ($itm1, $itm2) =
>>>> split(/\~/,$aA[$cC]); # note the scope
>>>> if
>>>> (!exists($vHsh{$itm1}{$itm2}{"SYSTEM"})) { #--- also tried
>>>> defined
>>>> warn "Found [$itm1 $itm2]";
>>>>
>>>> $vHsh{$itm1}{$itm2}{"SYSTEM"} = "TEXT";
>>>> }
>>>> }
>>>> print Dumper(\%vHsh);
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>>> __________________________________________________________________
>>> Yahoo! Canada Toolbar: Search from anywhere on the web, and bookmark your
>>> favourite sites. Download it now
>>> http://ca.toolbar.yahoo.com.
>> use strict;
>> use Data::Dumper;
>> my %prodFnd;
>> $prodFnd{"101010"}{"S0"} = "text";
>> $prodFnd{"101010USED"}{"S0"} = "text";
>> print Dumper(\%prodFnd);
>> if (!exists($prodFnd{"101010"}{"S0"}{"SYSTEM"})) {
>> $prodFnd{"101010"}{"S0"}{"SYSTEM"} = "TEXT";
>> print "First<br>";
>> print Dumper(\%prodFnd);
>> }
>> if (!exists($prodFnd{"101010USED"}{"S0"}{"SYSTEM"})) {
>> $prodFnd{"101010USED"}{"S0"}{"SYSTEM"} = "TEXT";
>> print "Second<br>";
>> print Dumper(\%prodFnd);
>> }
>>
>>
>>
> _______________________________________________
> kw-pm mailing list
> kw-pm at pm.org
> http://mail.pm.org/mailman/listinfo/kw-pm
>
More information about the kw-pm
mailing list