in reply to Re^2: Print something when key does not exist
in thread Print something when key does not exist
"Hello Ken, I can't thank you enough for the time and effort spent on such detailed and fantastic analysis. This is your second answer to my two posts here on perl monks and I can say for sure that I have learnt so much from your answers than I could ever have by reading a book."
You've shown a genuine desire to learn and have put thought into your questions: I'm more than happy to help. As I often say, "A better question gets better answers."
"One follow up question, I never seen fat comma (=>) used in join. Is this because we wanted the $sep to be quoted and fat comma will do that for us?"
As ++AnomalousMonk correctly identified, and went on to answer in more detail, this is a personal preference.
There's a quite a few functions whose first argument describes how it should operate, with the remaining arguments indicating what it should operate on. (Some exmples, just off the top of my head and in no particular order, would include: join, sprintf and pack.) In these cases, I often use a fat comma to separate the "how-to-operate" and the "what-to-operate-on" arguments. I find it can improve readability in many cases but, where it doesn't, I don't use it. It's just a personal style preference: use whatever you feel most comfortable with.
"Why does auto-vivification does not occur here?"
Autovivification has changed as Perl has matured: it used to happen a lot more than it does in more recent versions. (The changes mostly seem to be for optimisation purposes but that's purely a guess on my part.) As I've been using Perl since Perl3, and don't always recall every change that has been made, I do find that I sometimes need to check whether autovivification is occurring in a particular context: the script I provided was a case in point and a simple "use Data::Dump; dd \%data;" at the end of the code confirmed what I thought was happening.
$name is known to be a key of %data because it was returned by keys %data; therefore, $data{$name} doesn't need to be autovivified to check for $data{$name}{$_}. If there's no $data{$name}{$_} key, it doesn't need to be autovivified because, in the boolean context, it's known to be FALSE and that's all that needs to be known; it's not, for instance, being used as an lvalue or passed as an argument.
If $name had come from another source and $data{$name} didn't exist, it would need to be autovivified; however, $data{$name}{$_} still wouldn't need to be autovivified for the reasons just given.
Here's a quick test to clarify those points:
$ perl -Mstrict -Mwarnings -MData::Dump -le ' my %x = (a => { B => 2 }); for my $key (qw{a b}) { print join "^" => map { $x{$key}{$_} || "undef" } qw{B C}; dd \%x; } ' 2^undef { a => { B => 2 } } undef^undef { a => { B => 2 }, b => {} }
$x{b} was autovivified where it was needed. None of $x{a}{C}, $x{b}{B} or $x{b}{C} were autovivified because they weren't needed beyond the boolean context where just knowing that they didn't exist was sufficient.
If I'm ever not 100% sure, I find a quick check is faster than trying to analyse all the code involved and can avoid potential late night debugging sessions.
You'll find some more information on this in perldata and perlref.
"What makes perl decide to go the OR (||) route to map null string to join function?"
There are several things that are deemed to be FALSE in a boolean context. An undefined value is one of these. See "perlsyn: Truth and Falsehood" for more details.
-- Ken
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Print something when key does not exist
by AnomalousMonk (Archbishop) on Apr 06, 2014 at 20:39 UTC | |
by kcott (Archbishop) on Apr 06, 2014 at 23:09 UTC | |
|
Re^4: Print something when key does not exist
by jaypal (Beadle) on Apr 06, 2014 at 21:07 UTC |