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