Documentation seems sparse regarding when
statements outside of given
blocks. It is said the when
can be used when a 'topic' has been set, but when exactly is a topic considered set? Consider these cases:
for (@arr) {
when { }
}
Seems this is the default, basic case, but I couldn't get even this working on my perl 5.14.2 - Turned out this was just another bash quoting issue.$ perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }'
prints nothing. What am I doing wrong?
for my $elem (@arr) {
when { }
}
Would this work? Will $elem automatically become the topic for when
to use?
for (@arr) {
$_ = some_expression($_);
when { }
}
Would this work? Can the topic be set inside the loop?
Also, is there any difference when each of the above code segments uses foreach
instead of for
?
Basically, I'm very unclear on the topic of topics, so please enlighten me.
It's a shell command construction error.
perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print 'boom'} }'
should be
perl -Mfeature=switch -e 'foreach (qw(a b c)) { when (/a/) {print '\''boom'\''} }'
We can switch to double quotes to simplify
perl -Mfeature=switch -le'foreach (qw(a b c)) { when (/a/) {print "boom"} }'
And we can simplify further
perl -E'for (qw(a b c)) { when (/a/) { say "boom" } }'
Keywords for
and foreach
are one and the same to Perl.
Note that 5.18 marked given
and when
as experimental. It won't go away, but it will change. I explain what's going on here.
No, when
doesn't use $elem
; it always uses $_
.
Yes, you can change $_
inside of for
or given
if you so desire. Note that foreach loops aliase their topic to the element being visited, so changing one changes the other.
my @x = qw( abc def );
for (@x) { $_ = uc($_); }
say @x; # ABCDEF
Ikegami spotted your actual problem. Regarding the other questions:
The two topicalizers are for
/foreach
and given
. Other constructs that set $_
(the topic variable), are not considered topicalizers (e.g. map
or grep
).
If you run a foreach-loop with an explicit loop variable, the loop isn't considered to be a topicalizer. Therefore,
for my $x (1..3) {
local $_ = $x;
say when 2;
}
will work for the first iteration, but then die (Can't "when" outside a topicalizer) once the when
is exited.
The given
is different in that it doesn't localize $_
, but gives a lexical $_
. That is, given (@a) { foo; }
is similar to { my $_ = \@a; foo; }
(I think this might be fixed).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With