-
Notifications
You must be signed in to change notification settings - Fork 1
temp with %hash<key> or @array[$i] produces unwanted artefacts #5420
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
Comments
From @zoffixznetusing `temp` on a hash key restores its original value when we leave the scope, while other keys are free to be modified: m: my %h = foo => 'bar'; { temp %h<foo> = 'meow'; }; say %h m: my %h = foo => 'bar'; { temp %h<foo> = 'meow'; %h<not-foo> = 42; }; say %h However, if the `temp`ed key did not exist in the original hash, it WILL exist after leaving the scope. Expected behaviour: the key does not exist: m: my %h = foo => 'bar'; { temp %h<not-foo> = 'meow'; }; say %h This issue was originally mentioned in https://rt.perl.org/Ticket/Display.html?id=126447 and currently-fudged tests exist: Raku/roast@9977e56 |
From @zoffixznetThis occurs for arrays too actually: m: my @a; { temp @a[10] = "foo" }; dd @a |
From @zoffixznetCurrently skipped spectests in place: Raku/roast@0ec97817b7 |
From @smlsSeems like a dubious spectest to me. Are you sure that this is the intended behavior? I mean, it's a desirable feature in and of itself, but I don't see how it can possibly work (in the general case), unless you extend the Perl 6 container system or severely restrict what kind of expressions `temp` accepts. As it is now, `temp` accepts an arbitrary expression, and works fine as long as the expression ends up returning an rw container: sub a0 is rw { @array[0] } In fact, there's nothing fundamentally special, design wise, about the expression `@array[$i]` - it's just a postcircumfix operator returning an rw container. In any case, `temp` gets passed an rw container (i.e. a Scalar or Proxy) and has no idea if it came from an array/hash or not. This means that `temp` has to use "fetch" to remember the original value, "store" to override it with the replacement value, and then at the end of the block another "store" to restore the original value. I don't know of any public mechanism for `temp` to do a :delete operation on the array/hash from which the rw container originated, or even to know when it would need to do so. Of course, `temp` could hack into the non-public internals of the special Scalar's that are returned by Array and Hash for nonexistent elements. But this would violate the Perl 6 design principle that the built-in data structure classes are not "special" or "hard-coded", i.e. that CPAN modules should be able to implement their own similar data structure classes in pure Perl 6 code and benefit from all the same things that the built-ins do (like postcircumfix []). Another solution would be to no longer allow `temp` to accept a general Perl 6 expressions, and instead instruct the parser to expect a variable or variable-like construct to follow. But where do you draw the line, e.g. will `temp %hash<a>[0]` be allowed? And what if a CPAN module wants to add an alternative operator that should function like .[] or .{}? TL;DR: Unless I'm missing something obvious, this ticket is not just a [BUG] but an [RFC] involving larger design issues that would need TimToady to weigh in, or jnthn who implemented/(designed?) the current iteration of the container system. It's possible that the least bad option is to simply accept that `temp` cannot restore the non-existence of array/hash elements. |
From @zoffixznetThanks. I removed the tests (Raku/roast@25869ebe13 ) For the ticket itself, there was a discussion yesterday and while we may not do anything for the Discussion: http://irclog.perlgeek.de/perl6-dev/2016-08-08#i_12986816 |
From @ronaldxsOn Tue, 09 Aug 2016 08:46:30 -0700, cpan@zoffix.com wrote:
The IRC discussion seems to leave temp hash keys {temp %h<k>} as somewhat of an abstract concern but thought I might mention a substantial reason to leave the ticket open. This tick stems from an issue with %*ENV resolved with RT126447. I may be missing an implicit understanding of the effect on %*ENV but just in case ... ron@ron-laptop:~$ perl -Mstrict -wE 'say "before"; system("printenv | grep -i none_such"); sub f { local ron@ron-laptop:~$ perl6 -e 'say "before"; shell "printenv | grep -i none_such; exit 0"; sub f { temp %*ENV{"none_such_$*PID"} = "marker"; say "during"; shell "printenv | grep -i none_such; exit 0"}; f(); say "after"; shell "printenv | grep -i none_such; exit 0"' Note that in the perl6 version printenv sees the undefined environment variable in "after". I came across this ticket from researching what seems to be a related ticket RT125398 |
Migrated from rt.perl.org#128544 (status was 'open')
Searchable as RT128544$
The text was updated successfully, but these errors were encountered: