Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Re: exists() unexpected behavior

by Rhandom (Curate)
on Apr 12, 2001 at 09:29 UTC ( [id://71957]=note: print w/replies, xml ) Need Help??


in reply to Re: exists() unexpected behavior
in thread exists() unexpected behavior

Is this that hard to change? (A naive question coming from somebody who codes IN perl but doesn't code the perl) Autovivication is a great thing so that constructs such as $a->{b}->{c} = 'd' create the entire structure without much tedium. That being said, looking at a file existence check of (-e "/a/b/c/d") or a system ls on a directory doesn't go about creating directories (I know, I know ... apples to oranges). Is this planned behavior. It seems that it would make good sense in an assignment operator, but that is all. Does it have to occur whenever it tries to back up the reference line?
OK, I've probably put my foot in my mouth because I haven't looked at the back end of Perl.

Replies are listed 'Best First'.
Re: Re: Re: exists() unexpected behavior
by knobunc (Pilgrim) on Apr 12, 2001 at 16:49 UTC

    See the other replies for why Perl does this. I have a subroutine I use when I want to get a value from a nested structure only if it exists. You can modify this to do the existence check only if you need that.

    use Carp; sub safe_get { my $handle = shift; my $ptr = $handle; for (my $i = 0; $i < @_; $i++) { my $key = $_[$i]; # Handle each type my $type = ref $ptr; if (not defined $type) { croak "Not a reference.\n"; } elsif ($type eq 'HASH') { return undef unless exists $ptr->{$key}; $ptr = $ptr->{$key}; } elsif ($type eq 'ARRAY') { croak "Non numeric array index '$key'." unless $key =~ m/^\+?\d+$/; croak "Bad array thing '$key'." unless $key >= 0; return undef unless $key < @$ptr; $ptr = $ptr->[$key]; } else { croak "Unable to handle type '$type'"; } # Is this the end? return $ptr if $i == @_ - 1; } } # Usage my %foo = {bar => [1, {baz => 'xyzzy'}] }; my $value1 = safe_get(\%foo, 'bar', 1, 'baz'); my $value2 = safe_get(\%foo, 'bar', 2, 'baz'); # $value1 is 'xyzzy', $value2 is undef

    -ben

Re: Re: Re: exists() unexpected behavior
by merlyn (Sage) on Apr 12, 2001 at 18:23 UTC
    Well, technically, that's exactly what needs to be fixed, but it'd be hard to fix it. The dereferencing operator at the tail end knows if it's in an lvalue (being assigned to) or rvalue (being accessed) context, but apparently, the information is not available to the dereferencing operators in the middle of the chain, and that'd be messy to add. Apparently, it requires adding a new bytecode to Perl, and that has a lot of potential for breaking many more things than it fixes.

    For now, the known workaround is to step carefully down the tree, calling exists at each level before proceeding to the next. In practice, I've not been bitten by this, but maybe it's because I had been bitten once or twice while practicing with references. {grin}

    -- Randal L. Schwartz, Perl hacker

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://71957]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (9)
As of 2024-04-18 07:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found