7

If a perl-hash is declared like so:

use warnings;
use strict;

my %h;

I can then check for the existence of keys within this hash with exists:

if (exists $h{k3}) {
  print "k3 exists\n";
}
else {
  print "k3 doesn't exist\n";
}

Since k3 does not exist, the script prints k3 doesn't exist.

I can also check for the existence ka in k3:

if (exists $h{k3}{ka}) {
  print "k3 ka exists\n";
}
else {
  print "k3 ka doesn't exist\n";
}

Unfortunately, this creates the key k3, so that another

if (exists $h{k3}) {
  print "k3 exists\n";
}
else {
  print "k3 doesn't exist\n";
}

now prints k3 exists.

This is a bit unfortunate for my purposes. I'd rather not want perl to create the k3 key.

I can, of course, check for ka within k3 with something like

if (exists $h{k3} and exists $h{k3}{ka})

which doesn't create the key k3. But I wonder if there is a shorter (and imho cleaner) way to check for ka within k3.

Edit The question was marked as duplicate. Unfortunately, the only answer in the referred question that mentions no autovivification has only one upvote there, and is not marked as accepted answer. For my purposes, the no autovification is the feature I needed to know (and that I was unknowingly after). So, I leave my question here as I think the accepted answer in the other question is not the optimal one.

Unfortunatly, nobody so far answered with no autovification which I would like to accept. I might therefore answer my own question.

René Nyffenegger
  • 39,402
  • 33
  • 158
  • 293
  • 12
    “Autovivification” usually does what you want it to: let intermediate references spring into existence. For testing nested structures with `exists`, this is unfortunate. `and`ing the various levels together is the usual approach, but [`no autovivification`](https://metacpan.org/module/autovivification) may help (I've never used that module). – amon Jun 04 '13 at 20:24
  • 2
    [`no autovivification`](http://search.cpan.org/perldoc?vivification) – mob Jun 04 '13 at 20:24
  • 3
    @amon: You should promote that to an answer – Borodin Jun 04 '13 at 21:39

1 Answers1

2

The simplest thing is to nest your ifs:

if (exists $h{k3}) {
  print "k3 exists\n";
  if (exists $h{k3}{ka}) {
    print "k3 ka exists\n";
  }
  else {
    print "k3 ka doesn't exist\n";
  }
}
else {
  print "k3 doesn't exist\n";
}
Marc Shapiro
  • 571
  • 2
  • 2
  • 1
    Interesting use of the word "simplest" :-) I would say the simplest thing is to use "no autovivification". – Dave Cross Jun 05 '13 at 08:38
  • Simplest in that it only moves around the code he has without adding any more. Also simplest in that it doesn't perform redundant tests. – Marc Shapiro Jun 05 '13 at 23:42