Dieser Post wurde aus meiner alten WordPress-Installation importiert. Sollte es Darstellungsprobleme, falsche Links oder fehlende Bilder geben, bitte einfach hier einen Kommentar hinterlassen. Danke.
A new task at work made me hunting warnings, mostly "Use of uninitialized value" messages. One simple line creating such noise was
my $country_href = $countries->{$setup{countrycode}} || 0;It turned out, that $setup{countrycode} wasn't guaranteed to be defined and Perl complained.
My fix was quick and simple:
my $country_href = ($setup{countrycode} and $countries->{$setup{countrycode}}) || 0;Assuming that the ISO committee never assigns "00" as country code :-)
This one-line-commit started a little discussion (and I appreciate source code discussions) about the ( ) result. I know think, that ("true" and 3) evaluates 3 only of "true" is true and returns the value of the last element. This makes sense, since the whole and can't be true unless the last item is also true when being used as a condition.
I try to avoid adding more and more code lines unless it improves readability or has some other advantage, so adding a multi-line if-then-else-monster wasn't an option.
What do you think? How would you remove that warning? (Please don't tell me to remove "use warnings;" from the file :-) )
7 Kommentare. Schreib was dazu-
anon
15.09.2011 10:09
Antworten
-
anonymous
15.09.2011 10:50
Antworten
-
Chas. Owens
15.09.2011 11:54
Antworten
-
A. Guest
15.09.2011 15:17
Antworten
-
Ricky Morse
15.09.2011 16:40
Antworten
-
Alexander Hartmaier (abraxxa)
15.09.2011 17:14
Antworten
-
Richard Huxton
15.09.2011 20:56
Antworten
Use a defined-or clause in the hash ref (perl 5.10+ only) and take advantage of autovivification
my $country_href = $countries->{ $setup{countrycode} // 0 };
http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Decoding_table
AA, ZZ, all starting with X and some starting with Q are reserved. To comply with the ISO standard, use any of those instead of 0.
I would expect to see that written as
my $country_href = $setup{countrycode} && $countries->{$setup{countrycode}} || 0;
to avoid having to use the parentheses. Using the short-circuit logic of && and || in this way is a pretty common idiom; however, it is often better to find out how the undef value got to this point than to just silence the warning. Often an undef value is a sign of either a programming error or a design flaw.
my $country_href = (
$setup{countrycode} and exists $countries->{$setup{countrycode}}
) ? $countries->{$setup{countrycode}} : 0;
Makes it easy to see what gets assigned to $country_href, works with '00' as country code.
Hi! I would probably do something like:
my $country_href = exists($setup{countrycode}) ? $countries->{$setup{countrycode}} : 0;
But I don't think there's anything wrong with using the "and" format. I would, however, make the test exists (or, possibly, defined) instead of just testing the boolean value.
put it into a no warnings 'uninitialized'; block if you don't care about it being undef.
If you are running anything recent (perl 5.10+)
my $country_href = $countries->{$setup{countrycode}} // 0;