I'm getting this expected output
perl -MData::Dumper -e 'print Dumper do q(./dotest.pl)'
$VAR1 = [
1,
2,
3,
4
];
while dotest.pl
is
use strict;
use warnings;
my $x=1;
if ($x) {
my $ret = [
# map { my %h = (x => $_); \%h }
1..4
];
}
sub foo { 1 }
However, when I uncomment the map transformation, the oneliner doesn't output anything.
Is it a bug? perl is 5.34.0
You didn't check if an exception was caught by do
, but it didn't.
Aside from catching exceptions, it should behave the same as the following:
use strict;
use warnings;
use Data::Dumper;
sub f {
my $x=1;
if ($x) {
my $ret = [
map { my %h = (x => $_); \%h }
1..4
];
}
sub foo { 1 }
}
print Dumper f();
Like you, I get nothing from the do
version, but the above dumps an AoH.
So they don't behave the same. The do
version doesn't return the result of the last expression evaluated (the assignment) as it should. So yeah, it's a bug. And it's still present in 5.40.
It's some kind of context issue. Calling do
in scalar context works.
What you posted really pushes the limit of acceptable code, though :)
do BLOCK
has the same problem.
use strict;
use warnings;
use Data::Dumper;
print Dumper do {
my $x=1;
if ($x) {
my $ret = [
map { my %h = (x => $_); \%h }
1..4
];
}
sub foo { 1 }
};
And with do BLOCK
, we can have a look at the opcodes.
$ perl -MO=Concise,-exec do.pl
[...]
x <1> padsv_store[$ret:1274,1275] vKS/LVINTRO
[...]
See that v
? It's being evaluated in void context. The subroutine version above evaluates it in scalar context.
$ perl -MO=Concise,-exec,f sub.pl
main::f:
[...]
s <1> padsv_store[$ret:1274,1275] sKS/LVINTRO
[...]