Skip Menu |
Report information
Id: 128544
Status: open
Priority: 0/
Queue: perl6

Owner: Nobody
Requestors: cpan [at] zoffix.com
Cc:
AdminCc:

Severity: (no value)
Tag: Bug
Platform: (no value)
Patch Status: (no value)
VM: (no value)



Subject: [BUG] temp %hash<key> for non-existent key does not delete it
Download (untitled) / with headers
text/plain 851b
using `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 rakudo-moar d4ac15: OUTPUT«{foo => bar}␤» m: my %h = foo => 'bar'; { temp %h<foo> = 'meow'; %h<not-foo> = 42; }; say %h rakudo-moar d4ac15: OUTPUT«{foo => bar, not-foo => 42}␤» 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 rakudo-moar d4ac15: OUTPUT«{foo => bar, not-foo => (Any)}␤» This issue was originally mentioned in https://rt.perl.org/Ticket/Display.html?id=126447 and currently-fudged tests exist: https://github.com/perl6/roast/commit/9977e560ffddf6c47e621610dfbb384d3c20aa56
Subject: [BUG] temp with %hash<key> or @array[$i] produces unwanted artefacts
Download (untitled) / with headers
text/plain 179b
This occurs for arrays too actually: m: my @a; { temp @a[10] = "foo" }; dd @a rakudo-moar d4ac15: OUTPUT«Array @a = [Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any]␤»
Currently skipped spectests in place: https://github.com/perl6/roast/commit/0ec97817b7
Download (untitled) / with headers
text/plain 2.4k
Seems 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] } temp a0() = 42; 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. Unless I'm mistaken, the public interface of an rw container has just two operations: "store" and "fetch". 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.
Download (untitled) / with headers
text/plain 365b
Thanks. I removed the tests (https://github.com/perl6/roast/commit/25869ebe13 ) For the ticket itself, there was a discussion yesterday and while we may not do anything for the arrays, there was some conversation on doing something for the keys, so I'm going to leave the ticket open for now. Discussion: http://irclog.perlgeek.de/perl6-dev/2016-08-08#i_12986816
Download (untitled) / with headers
text/plain 1.5k
On Tue, 09 Aug 2016 08:46:30 -0700, cpan@zoffix.com wrote: Show quoted text
> Thanks. I removed the tests > (https://github.com/perl6/roast/commit/25869ebe13 ) > > For the ticket itself, there was a discussion yesterday and while we > may not do anything for the > arrays, there was some conversation on doing something for the keys, > so I'm going to leave the ticket open for now. > > Discussion: http://irclog.perlgeek.de/perl6-dev/2016-08-08#i_12986816
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 $ENV{"none_such_$$"} = "marker"; say "during"; system("printenv | grep -i none_such")}; f(); say "after"; system("printenv | grep -i none_such")' before during none_such_20493=marker after 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"' before during none_such_20395=marker after none_such_20395= 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


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org