-
Notifications
You must be signed in to change notification settings - Fork 571
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
readline/readdir does not assign to $_ implicitly. #16825
Comments
From @toddrCreated by @toddrWe've been experimenting with virtualizing directory interaction in I got a report about a problem with implcit assignment to $_ not working To try to clarify the problem we came up with this perl script. use strict;
use warnings;
BEGIN { *CORE::GLOBAL::readdir = sub { $_[0] } }
print "*** readdir assigns to \$_ implicitly\n";
while (readdir 'foo') {
print;
last;
}
print "*** readdir undef\n";
while (readdir undef) { # doesn't implicitly check defined()
print;
last;
}
print "*** \$_ = readdir 'foo'\n";
while ($_ = readdir 'foo') {
print;
last;
} I would have expected foo 2 times but instead I got this. The uninitialized *** readdir assigns to $_ implicitly Perl Info
|
From @tonycozSubject: readline does not assign to $_ implicitly. On Wed, 23 Jan 2019 19:02:36 -0800, TODDR wrote:
For anyone confused by the mismatch between the subject and body, Tony |
The RT System itself - Status changed from 'new' to 'open' |
From @GrinnzOn Wed, 23 Jan 2019 19:02:36 -0800, TODDR wrote:
The warning is from trying to print undef because the first call did not assign anything to $_. The second loop does not run at all. That's actually correct behavior since it returns undef, but if you instead use a defined false value like '' or 0, the condition still fails; this shows that the implicit defined check is also not being applied (only returning undef should fail the condition). -Dan |
From @tonycozOn Wed, 23 Jan 2019 19:02:36 -0800, TODDR wrote:
As discussed in IRC this happens due to the order in which ops are replaced with functions relative to where the "while (readline...)" -> "while ($_ = readline)" and "while ($x = readline)" => "while (defined($x = readline))" transformation is done. An op like readdir or readline is replaced with it's override in the block in toke.c around line 7211, ie. during tokenization, so the checks in Perl_newLOOPOP() and Perl_newWHILEOP() see an entersub instead of a readdir/readline. To fix it, I think we'd need to prevent readdir/readline being replaced in toke.c and do the check later, either in the new(WHILE|LOOP)OP(), or in a ck function. Tony |
@tonycoz How significantly would we be de-optimizing this to make it work? I guess the question I'm asking myself is: "Should we?" |
It would slow compilation a little, but I doubt it would make a noticeable difference. It shouldn't make any difference to runtime, except for the desired extra defined($_ = ... ) ops. The current behaviour is fairly surprising, so I don't think this should be WONTFIX. |
@tonycoz, @toddr, are we going to take any further action with respect to this ticket? |
I think it's still a bug (or at least surprising.) |
My bug in Test::MockFile is unfixable because of this if I recall correctly. |
Migrated from rt.perl.org#133795 (status was 'open')
Searchable as RT133795$
The text was updated successfully, but these errors were encountered: