http://www.perlmonks.org?node_id=1044821

david2008 has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I am aware that this item was discussed in perlmonks
http://www.perlmonks.org/?node_id=104789
but i don't understand the outcome.
If i have the following code

foreach my $item(@items) { eval { next if(is_problematic($item)); do_something($item); }; if($@) { warn "problem with $item $@"; } }
I get the warning exit eval via next.
My question is what the meaning of the warnings is and what harm does it do ?

Thanks,
David

Replies are listed 'Best First'.
Re: perl exit eval via next in a loop
by tobyink (Canon) on Jul 17, 2013 at 14:36 UTC

    The next, last and redo keywords are designed for jumping around within a loop structure. However, if other control structures (like subs and evals) are used within a loop, those three keywords can have the side-effect of jumping out of the other control control structures. This can sometimes be counter-intuitive, so if warnings are enabled, Perl will warn you about it.

    use strict; use warnings; # We're defining the "Foo" package inline here, but # imagine it's actually defined in a different file and # loaded with `use Foo`; { package Foo; sub foo { my $val = shift; # what on earth is this following line doing? next if $val < 3; } } # imagine that there are hundreds of other lines here for my $i (0..10) { Foo::foo($i); # why don't 0, 1 and 2 get printed?? print $i, "\n"; }

    The thing with the warnings pragma, is you shouldn't take the warnings it generates as absolute "do not ever do this" prohibitions. Instead, decide for yourself, on a case by case basis, about whether to rewrite the code to something better, thereby getting rid of the warning, or maybe deciding that actually your code is fine, and you can just put a no warnings "exiting" somewhere to disable the loop.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
      Thanks. This helped a lot.
Re: perl exit eval via next in a loop
by hardburn (Abbot) on Jul 17, 2013 at 14:30 UTC

    If there was an otherwise fatal error (like a die()) somewhere inside the eval, it will be captured and printed out in the warn. The $@ variable holds the error message that it would have die()'d with. The loop can then continue on as if nothing happened, and you have a nice little error message to help debug things.


    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.