Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^3: Exiting eval via next: is that so bad?

by SimonSaysCake (Beadle)
on Jul 01, 2019 at 14:50 UTC ( [id://11102240]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Exiting eval via next: is that so bad?
in thread Exiting eval via next: is that so bad?

Sorry, I can see why my example is confusing. Here's a slightly better one, more true to the production code:

#!/usr/bin/perl use strict; use warnings; use Scalar::Util qw(looks_like_number); my @times = (2, 4, 3, 1, 3.5, 2, 5); select((select(STDOUT), $|=1)[0]); TIME: for my $time_to_wait (@times) { print "Time to wait is: $time_to_wait\n"; local $@; eval { # Skip even numbers. die '__NOT_FATAL__' if !($time_to_wait % 2); verify_number($time_to_wait); # Skip numbers less than 3. die '__NOT_FATAL__' if ($time_to_wait < 3); verify_time($time_to_wait); 1; } or do { if($@ && $@ =~ /__NOT_FATAL__/) { next TIME; } print "Something went boom! ($@)\n"; }; print "Sleeping for $time_to_wait seconds ... "; sleep $time_to_wait; print "Done.\n"; } exit 0; sub verify_number { my ($arg) = @_; die "We died!" if !defined $arg; looks_like_number($arg) or die "We died!"; return; } sub verify_time { my ($arg) = @_; die "We died!" if !defined $arg; # Floats not allowed. int($arg) == ($arg / 1) or die "We died!"; return; }

Now imagine several more "verify" type calls within that same eval. Granted, it could be re-written to use a bunch more separate eval calls thus potentially allowing next calls outside/between them but in production those function calls are all very related and would die in similar ways. So I feel it comes down to what's more simple, cleaner? I think I might give the undermentioned Syntax::Keyword::Try package a try (swidt) since it does seem to support exiting via "next" calls.

-s1m0n-

Replies are listed 'Best First'.
Re^4: Exiting eval via next: is that so bad?
by haukex (Archbishop) on Jul 01, 2019 at 15:16 UTC
    Now imagine several more "verify" type calls within that same eval.

    Yeah, I figured it was something like that. Personally I still wouldn't use that "eval/die with a fixed string" pattern, and instead maybe wrap each call in an eval, or to make it look a little nicer, perhaps Try::Tiny. Of course, this being Perl, other ways come to mind :-) Say you've got a bunch of verify_* functions that you can't change and whose errors are fatal, but you want nonfatal versions of them:

    use warnings; use strict; # UUT use Scalar::Util qw/looks_like_number/; sub verify_number { my ($arg) = @_; die "not a number" if !defined $arg; looks_like_number($arg) or die "not a number"; return; } # wrap the funcs my @funcs = qw/ verify_number /; for my $f (@funcs) { my $orig = \&{$f}; my $wrapped = sub { eval { $orig->(@_); 1 } }; { no strict 'refs'; *{$f.'_nf'} = $wrapped } } use Test::More tests => 4; # helper sub exception (&) { eval { shift->(); 1 } ? undef : ($@ || die "\$@ was false") } ok !exception { verify_number("3.14") }; like exception { verify_number("foo") }, qr/\bnot a number\b/i; ok verify_number_nf("3.14"); ok !verify_number_nf("foo");

    Of course you don't need to install the wrapped versions into the symbol table, a hash would work fine too.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11102240]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-25 16:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found