in reply to Re: Autovivification not working?
in thread Autovivification not working?

It's still the same deal. Your hash element has been autovivified and set to undef. This is what the warning is - you are using the undef as a number. If your hash had not been autovivified, your would have received a "Expected reference...." error when trying to access the value.

The way you have avoided the warning is the correct way to do it, although you can be slightly more compact with:

$self->{hash}{$subject} ||= 0;

In summary, you are trying to fix the wrong problem. Perl isn't being tricky this time. All it's doing is warning you that it is turning an 'undef' into a '0' for the addition. This is what you want.

____________________
Jeremy
I didn't believe in evil until I dated it.

Replies are listed 'Best First'.
Re: Re: Re: Autovivification not working?
by Juerd (Abbot) on Dec 20, 2001 at 19:41 UTC
    --, ++, -=, += and friends shouldn't complain about undefined variables, according to documentation.
    That's why perl -wMstrict -e'my $a = undef; $a++;' does not complain, nor does $hash{foo}++.

    But when the hash in quesion is tied AND a hashref AND in another hash, perl suddenly _does_ complain.
    I tried narrowing it down to the essential bits again, succesfully this time.
    As you can see in the paste below, everything is fine with the second one, which would be exactly the same if it were tie()d.

    2;0 juerd@ouranos:~$ cat test.pl #!/usr/bin/perl -w use GDBM_File; use strict; unlink 'karmatest'; my $hashref = { hash => {} }; $hashref->{object} = tie %{ $hashref->{hash} }, 'GDBM_File', 'karmates +t', GDBM_WRCREAT, 0640; sub resolve { return \ $hashref->{hash}{$_[0]}; } # Warning! ${ resolve('this one does not exist') } += 2; # now, the same, but without tie: my $second = { hash => {} }; sub resolve_again { return \ $second->{hash}{$_[0]}; } # No warning! ${ resolve('this one does not exist') } += 2; 2;0 juerd@ouranos:~$ perl test.pl Use of uninitialized value in addition (+) at test.pl line 13.


    I think my inability to express what I mean in English is the biggest problem here :(

    2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

      --, ++, -=, += and friends shouldn't complain about undefined variables, according to documentation.

      But you aren't using a variable, you are using a tied hash. I don't have the right modules installed, so try using B::DeParse to see what perl is doing to your program. <BS mode on> I haven't checked this but I bet perl is turning your 'variable' into a function call to something like (I last read the tie page many moons ago) $resolve->STORE('this one does not exist', $resolve->FETCH('this one does not exist') + 2)  <BS mode off>

      Let me know what it B::DeParse does to your code - I'm interested.

      Read more about tied hashes here.

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.

        Had tried that before, but B::Deparse doesn't turn hash operations on tied hashes into their corresponding method calls. But since there's no tie method for +=, I guess your explanation must be right.

        Thanks!

        2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$