perl5.10, give back our $_
perl5.10 added given keyword. very nice.
However, given("foo") does my $_ = "foo"
(lexical $_
) implicitly.
This means it does not work code using local $_
in given block. like this:
use 5.010;
sub foo(&$) {
my ($code, $value) = @_;
local $_ = $value;
$code->();
}
foo { print $_ } "foo"; # => "foo"
given ('xxx') {
foo { print $_ } "foo"; # => "xxx"
}
this occurs even List::Util.
use 5.010;
use List::Util qw/first/;
given ('xxx') {
my $test = first { $_ eq 'xxx' } qw/ bar baz /;
# $test => bar
}
or Try::Tiny (POD described this point.)
use Try::Tiny;
given ('xxx') {
try {
die "error";
} catch {
warn $_; # => "xxx"
}
}
I think we can avoid unnecessary problems by given() make local $_
instead of lexical $_
.
What do you think?
of course, It may be there is the purpose of lexical scope that I have not understand.(I dont read all p5p logs.)
and, We can use global $_
this way even inside lexical $_
scope.
given ('xxx') {
foo { our $_; print $_ } "foo"; # => "foo"
}
or
given ('xxx') {
foo { print $::_ } "foo"; # => "foo"
}
Ugh. This might be a case of “we didn’t think about that so it seemed like a good idea”, but I’m not sure. The thing is that
given
copies the value into$_
, unlikeforeach
which aliases$_
to the value.I suggest you file a bug against Perl, and let p5p hash it out.
In the meantime, note that you can just as well use
for('xxx')
anywhere you would writegiven('xxx')
, and the code will in practice work identically. (The difference is what happens if the code inside the block modifies$_
, and whether global references to$_
work. And that some people find your code weird when you useforeach
on single values.)Not sure if the whole 'lexical $_' thing was thought out completely beyond 'seems like a good idea', including the part about 'our $_' restoring global $_ (so if you want to localise the value passed to 'given' so it can be used in the dynamic, not lexical scope of the given block, you need to do something unpleasant like 'local our $_ = $_' or 'local $::_' as 'local $_' throws 'Can't localize lexical variable $_')
given
's semantics can be useful, but sometimes aren't. Mixing two very different scoping systems can be confusing. Fortunately, you can usefor
instead ofgiven
if you want the traditional dynamic scope.