-
Notifications
You must be signed in to change notification settings - Fork 598
Open
Description
Description
Given an if/else branch, such as the example below, it seems like a reasonable expectation that both branches behave identically with regard to entering a new scope - or not doing so.
sub foo {
my $x = $_[0];
if ($x) {
return 1
} else {
return 0
}
}
But they don't. The else branch is wrapped in an ENTER/LEAVE pair, but the if branch is not.
5 <;> nextstate(main 3 -e:1) v ->6
- <1> null K/1 ->-
7 <|> cond_expr(other->8) K/1 ->c
6 <0> padsv[$x:2,9] s ->7
- <@> scope K ->-
- <;> ex-nextstate(main 5 -e:1) v ->8
a <@> return K ->b
8 <0> pushmark s ->9
9 <$> const[IV 1] s ->a
h <@> leave KP ->b
c <0> enter ->d
d <;> nextstate(main 7 -e:1) v ->e
g <@> return K ->h
e <0> pushmark s ->f
f <$> const[IV 0] s ->g
That's not always the behaviour. In the following example, both branches are wrapped in an ENTER/LEAVE pair:
$ perl -MO=Concise,foo -e 'sub foo { $x = $_[0]; if ($x) { local $x = 2 } else { local $x = 3 }}'
main::foo:
...
5 <;> nextstate(main 2 -e:1) v:{ ->6
- <1> null KP/1 ->-
7 <|> cond_expr(other->8) K/1 ->f
- <1> ex-rv2sv sK/1 ->7
6 <#> gvsv[*x] s ->7
d <@> leave KP ->e
8 <0> enter ->9
9 <;> nextstate(main 4 -e:1) v:{ ->a
c <2> sassign sKS/2 ->d
a <$> const[IV 2] s ->b
- <1> ex-rv2sv sKRM*/LVINTRO,1 ->c
b <#> gvsv[*x] s/LVINTRO ->c
k <@> leave KP ->e
f <0> enter ->g
g <;> nextstate(main 6 -e:1) v:{ ->h
j <2> sassign sKS/2 ->k
h <$> const[IV 3] s ->i
- <1> ex-rv2sv sKRM*/LVINTRO,1 ->j
i <#> gvsv[*x] s/LVINTRO ->j
-e syntax OK
The inconsistency seems undesirable because:
- If a branch should enter a new scope but does not, buggy behaviour may result
- If a branch needlessly enters a new scope, that harms performance
Steps to Reproduce
perl -MO=Concise,foo -e 'sub foo { my $x = $_[0]; if ($x) { return 1 } else { return 0 }}'
Expected behavior
Both branches have consistent scope behaviour.
Perl configuration
Standard blead, v5.36
Metadata
Metadata
Assignees
Labels
No labels