in reply to Question about loops and breaking out of them properly

Without a label, next/last/redo affects the closest (innermost containing) loop.

for my $y ( ... ) { for my $x ( ... ) { next; } }
is equivalent to
Y: for my $y ( ... ) { X: for my $x ( ... ) { next X; } }

To go to the next pass of the outer loop, you can use the following:

Y: for my $y ( ... ) { X: for my $x ( ... ) { next Y; } }

In your example, the next is inside an if statement's body (not a loop), which is inside a foreach loop's body. It will go to the next pass of the only/foreach loop.


Notes

In your example, the next isn't in the grep "loop". It's in the if statement's body which is executed once the grep is complete.

You should not use next/last/redo in the callback of the grep operator.

Be careful. { ... } as a while statement is a loop. This means that

for ( @a ) { { last; } say; }

is equivalent to

for ( @a ) { say; }