Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

exists (EXPR), autovivified and conditionals

by barrd (Canon)
on Sep 28, 2003 at 13:56 UTC ( [id://294744]=perlquestion: print w/replies, xml ) Need Help??

barrd has asked for the wisdom of the Perl Monks concerning the following question:

Hello there all,
I have a couple of questions after trying to solve a small problem in a programme I am currently working on which lead me into deeper water.

The basic synopsis of the problem was creating a conditional with exists using an if / else construct. This didn't work, so a RTFM session followed.

(Q1) WTF does autovivified mean?
From the dox: "...The element is not autovivified if it doesn't exist..."

There is no such word in the English language, there is however "auto" which in this context I take to mean automated and "vivified" which means "To endue with life; to make to be living; to quicken; to animate".

The point being I believe (maybe incorrectly) that this could be the crux of my problem trying to use else.

(Q2) Why no conditionals except if and unless?
A broken example (simplified from a friend):

... use CGI qw/:standard/; my $q = CGI->new(); my $level = $q->param('level'); my %run_level = ('foo' => \&foo, 'bar' => \&bar, 'default' => \&default ); if (exists $run_level{$level}) { &{ $run_level{$level} }; } else { default(); } sub foo { return "Sub foo called"; } sub bar { return "Sub bar called"; } sub default { return "Sub default called"; }

This, for those of you who know what I'm on about doesn't work so I came up with something along the lines of (which works):

default() unless exists $run_level{$level}; exit unless exists $run_level{$level}; # or add exit into default() &{ $run_level{$level} };

Which just 'seems' wrong, there must be a cleaner, nicer way to do it. Please someone tell me there is :) It's weird because I have been using exists for years but never tried it before with else...

Any explanations or pointers would be most appreciated. Thank You.

Replies are listed 'Best First'.
Re: exists (EXPR), autovivified and conditionals
by bart (Canon) on Sep 28, 2003 at 14:24 UTC
    (Q1) WTF does autovivified mean?
    It is, as you guessed, a blend of "automatic", and "vivify", which here means "automatically brought to life". You can see it in action here:
    my %hash; $hash{"foo"}++;
    After this code is executed, the hash entry for "foo" will exist. That is the work of the autovivification.

    Now, what does it mean here? exist will not autovivify the hash element. All good news, no?

    There is however, one caveat, actually a case where this fails to do the proper thing. exists will not prevent autovivification of a multilevel hash, except for the very last level.

    my %hash; die "This is impossible!" if exists $hash{"foo"}{"bar"}{"baz"}; # However: use Data::Dumper; print Dumper \%hash;
    This prints:
    $VAR1 = {
              'foo' => {
                         'bar' => {}
                       }
            };
    
    So, even though the element $hash{"foo"}{"bar"}{"baz"} still doesn't exist, yet $hash{"foo"}{"bar"} now does, and it is an anonymous hash. Not good.

    (Q2) Why no conditionals except if and unless?
    Huh? exists and autovivification don't care about conditionals. Your example should work, and in fact, does. Only, you won't see a thing unless you do something with the value the subs return. Replace return with print and you'll see what it does. Or print the return value in your dispatcher (the if/else contruct).
Re: exists (EXPR), autovivified and conditionals
by PodMaster (Abbot) on Sep 28, 2003 at 14:26 UTC
    Well, if you keep R-ing TFM, it explains what auto-vivify means, basically it means to spring a new hash/array into existence. Example
    $a = {}; warn "exists " if exists $a->{a}{b}{c}{d}; use Data::Dumper; die Dumper($a); __END__ $VAR1 = { 'a' => { 'b' => { 'c' => {} } } };
    The key d in $a->{a}{b}{c}{d} doesn't exist, but look at the magic birth of those hashes ;)

    As for Q2, your diagnosis is faulty (whatever the problem is, it's not directly in the snippet you presented). BTW, I find $hash{$key}->() more syntactically appealing ;)

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

Re: exists (EXPR), autovivified and conditionals
by jasonk (Parson) on Sep 28, 2003 at 14:23 UTC

    The fact that it is not autovivified simply means that testing a non existant key with exists() will not create it. You don't indicate how your first example didn't work, but I suspect you expected to see it print 'Sub whatever called'. The only reason this doesn't work is that your subs are returning strings that you aren't doing anything with, change the returns to prints and I expect you will see what you were looking for.


    We're not surrounded, we're in a target-rich environment!
Re: exists (EXPR), autovivified and conditionals
by barrd (Canon) on Sep 28, 2003 at 14:53 UTC
    Thanks guys,
    Well that clears a few things up and I'll have to re-look into why my original code isn't working, it uses quite a few other modules so I may have inadvertently caused a third party error. Thanks again for the very prompt answers and I now have the confidence to go back and fix the problem knowing that there is a solution in there somewhere.

    I always love a challenge.

      I haven't run your example, but i can see a problem with the example code. "exists" checks for the key in the hash having been defined and pointing to a value or valid reference. Since you initialize the hash with references to the different subs, all those hash keys will exist. You should use "defined" or just a plain if(hash{key}), which does a similar thing but is more portable. Autovivified -- i had the same problem reading camel book, it assumes you know already. it means that if a variable does not exist it will spring into existence when you try to use it..the variable's value will be undefined/false until you do something to change that. Example: if(exists $hash{key}) if you don't declare/init this hash beforehand, the "exists" function will pretend the hash by that name is there. It will not crash your program, but will instead tell you if the particular key exists for this automatically created hash.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://294744]
Approved by bart
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2024-04-19 19:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found