Checking for a hash key creates a key

Given the following code

#!/usr/bin/perl use Data::Dumper; my %hash; my @colos = qw(ac4 ch1 ir2 ird kr3); foreach my $colo (@colos) { if(exists $hash{output}{$colo}) { print "$colo is in the hash\n"; } } print Dumper(\%hash); 

I have an empty hash that is being created. I have an array with several abbreviations in it. If I go through the array to see if these guys are in a hash, nothing is displayed in STDOUT, which is expected, but for some reason $ hash {output} is being created. It does not make sense. Everything I do is, if it exists. Where am I wrong?

+6
source share
4 answers

exists searches for the hash element in the given hash. Your code generates a hash
%{ $hash{output} } and checking for the hash element with the key $colo in this hash.

Try the following:

 if(exists $hash{output}{$colo}) { 

changed to

 if(exists $hash{output} and exists $hash{output}{$colo}) { 

You can, of course, write a subsection that hides this complexity from your code.

+6
source

Perl creates it because exists checks for the last specified key; it does not test recursively. It should not be created if you do this:

 if( exists $hash{output} && exists $hash{output}{$colo} ) { 

However, why do you need an additional key? Why not just $hash{$colo} ? Also if you, if you use strict , get a warning about an uninitialized value in $hash .

+3
source

You already have some good answers, but if you want to know more about this behavior, this is usually called “auto-wiring”, and there is a CPAN module that can be disabled if you prefer this to not happen.

+2
source

Actual code / hash is more complicated. Hash: $ rotation_hash {output} {oor} {$ colo} {$ type} {$ hostname} {file} {$ filename} = <html_status_code>

As others have said, when you ask about the existence of $foo{bar}{fubar} , Perl automatically creates $foo{bar} to check if $foo{bar}{fubar} . If you want to prevent this, you need to check if $foo{bar} exists, and if so, check if $foo{bar}{fubar} .

However, what caught my attention was your seven-layer hash. When your data structures begin to receive this complex, you really should use Perl Object Oriented coding. I know that many people are scared by Perl's object-oriented programming, but Perl is probably one of the easiest languages ​​for people who build OOP.

If nothing else, you use OOP for the same reason that you use use strict; . When I use strict; Perl will easily record where I used $foobar as a variable in one place, but then refer to it as $fubar in another place. You lose this protection with complex data structures. For example, you can place $rotation_hash{output}{oor} in one place, but $rotation_hash{oor}{output} in another place, and use strict will not catch it. But if you declare objects through package and use routines as methods and constructors, you will get it back.

Object-oriented design will also help you get rid of the need to keep track of the data structure. Objects process them for you, and you can focus on your coding. And you do not need to create multiple files. You can simply attach object definitions to the bottom of the file.

There are some excellent tutorials included in the Perl documentation. If you are new to OOP Perl, you should go through the tutorials and give it a try.

+1
source

Source: https://habr.com/ru/post/911213/


All Articles