... Perl certainly isn't doing what I mean... what's the rationale behind it?

Think a little harder about what you are asking for here, and see if you can come up with a sensible rationale for that. Here's a hint:

use strict; my %HoH; # case 1: { my $uid = 666; my $host = "foo.bar"; $HoH{$uid}{$host} = "hold onto this value"; } # what I meant there was: please autovivify $HoH{$uid} # and set its value to be an anon.hash ref # case 2: { my $uid = "something_unexpected_or_possibly_undef"; my $host = "who_cares_what_value_is_assigned_if_any"; if ( exists( $HoH{$uid}{$host} )) { do_something_appropriate(); } } # what I meant there was: please do not autovivify $HoH{$uid}; ins +tead, # do a separate check of hash-key existence for each level of hash + nesting
The "exists()" function would have to be the only one that treats dereferencing syntax in this more complicated manner, otherwise perl would not be able to do what you mean in the simple assignment usage. I'm really not familiar with how "exists()" is currently implemented, but I have a hunch that the only way it could be given this special behavior would be to have special operations at compile time that would rewrite your simple expression for you, creating the multi-stage test for hash key existence, which as you already know would need to be done. (And it would have to do the right thing for all variations and depths of dereferencing syntax -- ooh! a source-code filter that creates a recursive function... that sounds like fun!)

Would it be a good idea to make the "exists()" function actually work as a source-code filter at compile time? Food for thought (if you happen to like eating glass shards or sharp metal objects).

As others have pointed out, the problem is not with the "exists()" function, but rather with the process of dereferencing a hash structure. If perl simply refused to autovivify upper/outer hash keys in an HoH(oH...) structure, there would be much less need for using "exists()" (and no need to make it "special" in its treatment of dereferencing). Would you like to take away the ability to autovivify "upper/outer" hash keys in assignment statements? (If that's your preference, I think a lot of perl users would disagree.)

If you are having trouble with this repeatedly, you might want to make up your own version of "exists()" as a module -- but the calling syntax would have to be different... Maybe something like this?

use strict; use warnings; my %HoH; if ( Exists( \%HoH, "foo", "bar", "baz" )) { warn "Something is very strange\n"; } print scalar keys %HoH, "\n"; $HoH{foo} = { bar => { baz => "okay" }}; if ( Exists( \%HoH, "foo", "bar", "baz" ) and !Exists( \%HoH, "oops", +"uhoh" )) { print "All is well\n"; } print scalar keys %HoH, "\n"; # the following sub would actually be in a module: sub Exists { my ( $href, $topkey, @subkeys ) = @_; return unless ( ref( $href ) eq 'HASH' ); my $result = 0; if ( exists( $$href{$topkey} )) { $result = ( ref( $$href{$topkey} ) eq 'HASH' and @subkeys ) ? + Exists( $$href{$topkey}, @subkeys ) : 1; } return $result; }
(updated to fix a misplaced paren, and to add checks on the $href and @subkeys parameters)

Others could probably write that to be more elegant/compact, but it does what you want to do without violence to a long-established convention.


In reply to Re: Why does exists cause autovivication? by graff
in thread Why does exists cause autovivication? by Argel

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.