New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug in the 'exists' function #1288
Comments
From AMOSCM@eurodis.comHi This email has 3 sections: 1. perl version details from 'perl -V' Let me know if aI can be of help Thanks Section 1 - Perl version Summary of my perl5 (5.0 patchlevel 4 subversion 4) configuration: Characteristics of this binary (from libperl): Section 2 - the program $h{key1_x}{key2_x} = 'I exist'; # if (exists $h{key1_x}{key2_x}) ################################################################# # if (exists $h{key1_y}{key2_y}) ################################################################# print "Test 3 - Does key1 of the 2D hash exist (same key1 as test 2)?\n"; # Section 3 - The program output Test 1 - 2D hash element we know exists |
From [Unknown Contact. See original ticket]Chris Amos writes: | if (exists $h{key1_y}{key2_y}) Chris, if (exists &{$ref->{A}{B}{$key}}) { } Although the deepest nested array or hash will not undef $ref; HTH, |
From [Unknown Contact. See original ticket]
This has nothing to do with what function you call. It's the fact You're implicitly using the dereference arrow. Whenever you undef %h; And: undef %h; In fact, even undef $hr; From perlfunc: Note that the EXPR can be arbitrarily complicated as long as if (exists $ref->{A}->{B}->{$key}) { } if (exists $ref->{A}->{B}->[$ix]) { } if (exists &{$ref->{A}{B}{$key}}) { } Although the deepest nested array or hash will not spring into undef $ref; This surprising autovivification in what does not at first--or --tom |
From [Unknown Contact. See original ticket]
Either people aren't reading that, or they aren't understanding As a workaround for rvalued autovivification of dereferencing $ref->[$x][$y]{$key}[2] ) { ... } write this: if ($ref && Likewise, instead of writing this: $answer = $ref->[$x][$y]{$key}[2]; write this: $answer = $ref && Thank goodness && returns the real thing, not just 1 or 0. $answer = ( $ref && Eek. --tom |
From [Unknown Contact. See original ticket]
Should of course be if ( $ref->[$x][$y]{$key}[2] ) { ... } --tom |
From [Unknown Contact. See original ticket]Hi Guys I looked this up on my online docs before logging the "bug". My docs Thanks for looking at it though. I worked around it by checking the Cheers
|
From [Unknown Contact. See original ticket]
>> if (exists &{$ref->{A}{B}{$key}}) { } Although the deepest Tom> Either people aren't reading that, or they aren't Tom> As a workaround for rvalued autovivification of dereferencing Tom> $ref->[$x][$y]{$key}[2] ) { ... } Tom> write this: Tom> if ($ref && Tom> Likewise, instead of writing this: Tom> $answer = $ref->[$x][$y]{$key}[2]; Tom> write this: Tom> $answer = $ref && Tom> Thank goodness && returns the real thing, not just 1 or 0. Tom> $answer = ( $ref && Tom> Eek. Tom> --tom I put a module up on CPAN to do this. Hash::NoVivify allows you to do: |
From [Unknown Contact. See original ticket]
How does it know [] vs {}? --tom |
From @tamiasOn Wed, Mar 08, 2000 at 10:11:34AM -0700, Tom Christiansen wrote:
Probably calls ref on each step and checks whether it's ARRAY or HASH. :) Ronald |
From @nwc10On Wed, Mar 08, 2000 at 12:09:29PM -0500, Brent B. Powers wrote:
(explanation)
Would it be a good idea to add Tom's fuller explanation of the problem Note that the EXPR can be arbitrarily complicated as if (exists $ref->{A}->{B}->{$key}) { } existence just because its existence was tested, undef $ref; This surprising autovivification in what does not at ? The entry for defined in perlfunc appears to be completely lacking anything Nicholas Clark |
From [Unknown Contact. See original ticket]
You can say the same thing about *all* functions, operators, and --tom |
From @nwc10On Wed, Mar 08, 2000 at 10:31:11AM -0700, Tom Christiansen wrote:
I agree that it is true for all functins, but I think that it's most likely to Currently perlfunc's exists has a warning paragraph, but perlfunc's defined Nicholas Clark |
From [Unknown Contact. See original ticket]
They do. They do not autovivify their arguments. If I saw if ( $x{1} ) These also fail to autovivify their argument: if ( $x{1}[2] ) None of these autovivify their argument. However, many These, however, do: $x{1}[2]++; The [2] slot is all those if's are asking about. They do not --tom |
From [Unknown Contact. See original ticket]Tom Christiansen writes:
While this is absolutely correct, the behaviour you describe is *also* The bug is that $foo{bar} of rvalue_context( $foo{bar}->{baz} ) is executed in lvalue context. In fact it should be executed in Ilya |
From @nwc10On Wed, Mar 08, 2000 at 11:11:25AM -0700, Tom Christiansen wrote:
That's the important bit. Which I failed to express anywhere near clearly
Because it is easy for people to misunderstand what the argument to defined 1: copying the paragraph warning about this from the exists section to defined? Nicholas Clark |
From @nwc10On Wed, Mar 08, 2000 at 03:32:27PM -0500, Ilya Zakharevich wrote:
Aren't we arguing semantics here?
The "bug" is that perl doesn't have an rvalue context that encompasses the (As an aside I don't know if it's even easy to change rvalue context not I don't like the idea of the special case Current behaviour means you get 0 If we make rvalue context not autovivify for defined and exists, I'd argue bash-2.02$ perl -le 'print defined $ref; print $ref->{baz} - 0; print defined $ref' 0 bash-2.02$ Would this break many existing programs? Nicholas Clark |
From [Unknown Contact. See original ticket]
Yes, adding special magical cases doesn't seem the way to go.
We've had a long history of rvalue/lvalue existential crises. sub fx { $_[0] = $_[1] if @_ > 1 } printf "1: FOO exists %d\n", exists $H{FOO}; printf "4: BAR exists %d\n", exists $H{BAR}; Which of course produces: 1: FOO exists 0 Now, consider fx $H{FEE}{FI}{FO}{FUM}, "stuff"; Right now, only {FUM} is treated gingerly, which is consistent and Now, if that's not enough to strike fear into your heart, consider fx $A[ fN($i++) ]{ fS($i++) }[ fN($i++) ]{ fS($i++) }, "stuff"; See what I mean? --tom |
From @pjscottAt 05:14 AM 3/9/00 -0700, Tom Christiansen wrote:
Not that my brain has any chance of encompassing a fix, but can we agree in Not that I am undervaluing in any way your estimate of the difficulty of -- |
From [Unknown Contact. See original ticket]
I not think it is possible without breaking Perl, which, I would argue,
But that's not merely "observing" something. You're calling Here's another example: sysrw(FH, $buff[$i][$j]); Feel free to invent an understandable semantic here, but right now, It's all very well and good to say that since $a[$i] = "V" if $b[$i]; doesn't create $b[$i] but does create $a[$i], and since $a[$i][$j] = "V" if $b[$i][$j]; doesn't create $b[$i][$j] but does create $a[$i][$j], that this This is easy to voice, but that's not the hard problem. I don't understand how you can make this "work" without forbidding $a[fn($i)][fn($j)] = "V" if $b[fn($i)][fn($j)]; (Remember also that $i and $j may have been modified, or other And I don't know how you can make if (fn($a[$i][$j][$k]) { ... } work, where fn() may sometimes want to assign to its argument--the One other crippling concern here is that you cannot do lexical If you have some idea for how all this could possibly be done without --tom |
From [Unknown Contact. See original ticket]On Thu, Mar 09, 2000 at 11:44:56AM +0000, Nicholas Clark wrote:
Looks like *you* are. ;-)
This still does not make it a non-bug. We do not document when things $a = $b + 3; making $b into ['added', 'to',3] if $b were undef. Ilya |
From [Unknown Contact. See original ticket]Tom Christiansen <tchrist@chthon.perl.com>, writes: I was thinking it might be possible, but... The first rule, though, would have to unstrike the fear from our hearts. In thinking about multi-level auto_vivification, though, I thought of a In: my $a = { yes=>1 }; Is there any conflict between the code that is determining that This sort of situation gets worse in a multi-level auto-vivify An even worse problem for the multi-level auto-vivify would occur || Feel free to invent an understandable semantic here, but right now, That deterministic behaviour should remain - both functions || And I don't know how you can make I can see two ways, but both have problems. Either the argument || One other crippling concern here is that you cannot do lexical You cannot require such analysis to be done. You can however use || If you have some idea for how all this could possibly be done without Document it for 5.6. There is the possibility (but I'm rather -- |
From [Unknown Contact. See original ticket]John Macdonald wrote:
A third possiblilty (and I acknowledge that this is an extremely nasty When a thingy is auto-vivified in a (for want of a better term) chained I'm assuming, without looking at the code, that Perl can (or could) tell Pete |
From [Unknown Contact. See original ticket]Pete Jordan <pjordan1@email.mot.com> writes: That's essentially what I figured would be done for the tentative -- |
From [Unknown Contact. See original ticket]John Macdonald writes:
How could it?
SVOP (0x48c08) gv GV (0x47958) *a The only change would be omiting the rv2av nodes, and changing aelem
This (postponed autovivication) was a questionable "feature". But if
Do not think so. Some recursion in the autovivication magic will do it.
Does not matter. Autovivication magic would check that what it
Certainly it is not any bit harder than what we already do. Ilya |
From [Unknown Contact. See original ticket]Ilya Zakharevich <ilya@math.ohio-state.edu> writes: If the compiler is being changed so that in an rvalue context, @a = ( 1 ); As soon as the index 2 is used, the result of the right hand side Anyhow, this is not going to happen for 5.6, so let's drop this -- |
Migrated from rt.perl.org#2285 (status was 'resolved')
Searchable as RT2285$
The text was updated successfully, but these errors were encountered: