... or happy debugging!

TL;DR Upd: Use for instead of given, as Aristotle suggests.

Here are some code snippets to show what's wrong with given/when.

use 5.010; use strict; use List::MoreUtils qw/any/; given ('test') { when ('test') { say "any" if any {$_ == 2} (2, 3); } }

The above code prints nothing. Ok, let's change any to grep to see if it works:

given ('test') { when ('test') { say "grep" if grep {$_ == 2} (2, 3); } }

It prints "grep", just as planned.

Ok, to be perfectly honest all we always use warnings, and the first piece of code actually has to be as the following:

use warnings; given ('test') { when ('test') { say "any" if any {$_ == 2} (2, 3); } }

We were lucky and got a warning!

Argument "test" isn't numeric in numeric eq (==) at ...

But wait, what?

given ('test') { when ('test') { any {say $_} (2, 3); } }

It prints "test". Huh.

Gonna read some perldoc. It says:

given(EXPR) will assign the value of EXPR to $_ within the lexical scope of the block, so it's similar to

do { my $_ = EXPR; ... }

Ok, now we undestand what's the difference between any and grep here: implementation of any makes use of anonymous functions. Actually we have just a closure capturing that poor lexical $_.

The last one to make it obvious:

my $sub; given ('test') { when ('test') { $sub = sub {say;}; } } $sub->();

Well, you get the idea.