in reply to Missing error under strict
I boiled the problem down to this code
warn $]; #> 5.024001
$null = 1;
warn 'never' until $null = 666;
warn $null; #> 666
$one = 1;
warn 'never' until my $one = 666; # my !
warn $one; #> Warning: something's wrong
+at ...
B::Deparse didn't show anything suspicious
D:\tmp>perl -MO=Deparse tst_scope.pl
warn $];
$null = 1;
warn 'never' until $null = 666;
warn $null;
$one = 1;
warn 'never' until my $one = 666;
warn $one;
tst_scope.pl syntax OK
I also looked at B::Concise , but couldn't spot a difference in op-code flow.
D:\tmp>perl -MO=Concise,-src tst_scope.pl
18 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
# 1: warn $]; # 5.024001
2 <;> nextstate(main 1 tst_scope.pl:1) v:{ ->3
5 <@> warn[t2] vK/1 ->6
3 <0> pushmark s ->4
- <1> ex-rv2sv sK/1 ->5
4 <#> gvsv[*]] s ->5
# 3: $null = 1;
6 <;> nextstate(main 1 tst_scope.pl:3) v:{ ->7
9 <2> sassign vKS/2 ->a
7 <$> const[IV 1] s ->8
- <1> ex-rv2sv sKRM*/1 ->9
8 <#> gvsv[*null] s ->9
# 4: warn 'never' until $null = 666;
a <;> nextstate(main 1 tst_scope.pl:4) v:{ ->b
k <@> leave vK* ->l
b <0> enter v ->c
- <1> null vKP/1 ->k
f <|> or(other->g) vK/1 ->k
- <1> ex-not sK*/1 ->f
e <2> sassign sKS/2 ->f
c <$> const[IV 666] s ->d
- <1> ex-rv2sv sKRM*/1 ->e
d <#> gvsv[*null] s ->e
- <@> lineseq vK ->-
i <@> warn[t4] vK/1 ->j
g <0> pushmark s ->h
h <$> const[PV "never"] s ->i
j <0> unstack v ->c
# 5: warn $null; #> 666 ...
l <;> nextstate(main 1 tst_scope.pl:5) v:{ ->m
o <@> warn[t7] vK/1 ->p
m <0> pushmark s ->n
- <1> ex-rv2sv sK/1 ->o
n <#> gvsv[*null] s ->o
# 7: $one = 1;
p <;> nextstate(main 1 tst_scope.pl:7) v:{ ->q
s <2> sassign vKS/2 ->t
q <$> const[IV 1] s ->r
- <1> ex-rv2sv sKRM*/1 ->s
r <#> gvsv[*one] s ->s
# 8: warn 'never' until my $one = 666; # my !
t <;> nextstate(main 1 tst_scope.pl:8) v:{ ->u
13 <@> leave vK* ->14
u <0> enter v ->v
- <1> null vKP/1 ->13
y <|> or(other->z) vK/1 ->13
- <1> ex-not sK*/1 ->y
x <2> sassign sKS/2 ->y
v <$> const[IV 666] s ->w
w <0> padsv[$one:1,2] sRM*/LVINTRO ->x
- <@> lineseq vK ->-
11 <@> warn[t9] vK/1 ->12
z <0> pushmark s ->10
10 <$> const[PV "never"] s ->11
12 <0> unstack v ->v
# 9: warn $one; #> Warning: something's w
+rong at ...
14 <;> nextstate(main 2 tst_scope.pl:9) v:{ ->15
17 <@> warn[t11] vK/1 ->18
15 <0> pushmark s ->16
16 <0> padsv[$one:1,2] s ->17
tst_scope.pl syntax OK
D:\tmp>
My guess is still that until has an inconsistency in scope between compile-time and run-time and is erroneously resetting the lexical variable.
update
PS: I have problem to imagine practical code, where this bug is posing a problem.
Re^2: Missing error under strict (Perlbug: postfix 'until' has inconsistent scope)
by choroba (Cardinal) on Jul 23, 2019 at 13:48 UTC
|
It's a bug definitely. When using if instead of until, it outputs 666.
> I have problem to imagine practical code, where this bug is posing a problem.
The bug might manifest in other places, too, where it can cause serious headaches. I've already reported a bug for this Perl version, do you want to have your name mentioned in the Thanks section?
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
|
> . I've already reported a bug for this Perl version, do you want to have your name mentioned in the Thanks section?
sure and a link to the thread here please
something like
Thanks to Lanx who is normally to busy/lazy to report perlbugs
;-)
> The bug might manifest in other places, too, where it can cause serious headaches.
Sure that's why I've put so much effort into it. But I think the chances are <1%.
| [reply] |
|
Reported. I originally meant you should report it, but yeah, it's becoming a routine for me.
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] |
|
Re^2: Missing error under strict (Perlbug: postfix 'until' has inconsistent scope)
by Don Coyote (Hermit) on Jul 23, 2019 at 14:37 UTC
|
use strict;
use warnings;
use feature qw'say state';
{no strict; no warnings;
$three = 1;
say 'three' until $three++ == 3;
}
#Use of uninitialized value $two in say at SoPW_11103184.pm line 54
say 'two' until my $two = 2;
#say 'owt',$two;
say 'one' until state $one = 1;
say 'eno',$one;
{no strict; no warnings;
say $zero until $zero = 9;
}
say our $minone = 5 until $minone = 8;
say $minone;
# says '5' continuously
#say our $mintwo = 5 until 3 == $mintwo--;
#say $mintwo;
__END__
three
three
#say $two #uninit warning
eno1
8
Depending how the scope is declared determines if the assignment is fully evaluated
Can't find method 'say' in Module 'Died at ....' at ... | [reply] [d/l] |
|
| [reply] [d/l] |
|
I think I see the issue now
Basically my and state should be in the same scope, but state just holds value through iterations. So the my declaration should hold after the until modifer is executed, as it does with the state declaration.
I'm kind of wondering if 'our' gets restricted to what 'my' should do by this behaviour
First time I thought of using our to declare lexicality while using the same variable more than once in an expression.
| [reply] |
|
Re^2: Missing error under strict (Perlbug: postfix 'until' has inconsistent scope)
by Pascal666 (Scribe) on Jul 24, 2019 at 01:31 UTC
|
> I boiled the problem down to this code
Here you are initializing a seperate variable before the until, which is getting reset by the my inside the until. In my code I was initializing the variable inside the until, and then attempting to use it after. Seems like two different (but related) bugs to me.
> PS: I have problem to imagine practical code, where this bug is posing a problem.
My original code:
$count++ until my %boxes = fit($count, $quota, @sizes);
I wasn't sure about the scope when I wrote that line, but figured worst case I would get a compile error and move the my to the line above. Had a hell of a time figuring out why %boxes was always null when I tried to access it later (it should loop until %boxes is not null). | [reply] [d/l] |
|
My intention was to proof a bug in short code.
There is no possible explanation for an undefined value after the loop. Hence a bug.
> Here you are initializing a seperate variable before the until, which is getting reset by the my inside the until.
This statement doesn't really make sense, if the variables are different they can't reset each other.
As already explained does my have a compile time and a runtime effect, which are inconsistent in this case.
> Seems like two different (but related) bugs to me.
No. Everything else was explained.
> My original code:
> $count++ until my %boxes = fit($count, $quota, @sizes);
Thanks, nice example.
FWIW a workaround is to put the my declaration right before the loop.
| [reply] [d/l] [select] |
|
|