Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Anonymous sub as error handler

by CubicSpline (Friar)
on Sep 09, 2002 at 13:33 UTC ( [id://196257]=perlquestion: print w/replies, xml ) Need Help??

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

Greetings Monks.

I'm a beginning-intermediate Perl programmer and am currently working on a pretty simple DBI-based program. The focus of my question, however is not DBI-specific. Rather, it's a question about using (I believe) anonymous subroutines. What I want to do is catch it when one of my DBI statements fails. Depending on the error that caused the failure, I may want to just continue on or I may want to quit. My question is two-fold:

  1. Is what I'm trying to do actually an anonymous sub?
  2. Is this a good way to do what I want, or is there a better way?

Code follows, with questions in the comments:

# This is just an insert statement. What I want to do # is catch any errors, and then vary my actions based # on the error. Can I do this better? $newSeriesSth->execute() || &{ # is this an anonymous sub? if( $newSeriesSth->errstr =~ /duplicate/ ) { # this error is okay, i don't want to quit print "Trying to insert duplicate row.\n"; } else { # some other error, better safe to quit now. die("Unhandled error. DBI says: " . DBI->errstr); } };

Now, given that this is acceptable programming (which it may not be), the special bonus question is why do I get this error message while running this code?
Can't use string ("1") as a subroutine ref while "strict refs" in use at line 167 (Line 167 is the if(..) statement).

~CubicSpline
"No one tosses a Dwarf!"

Replies are listed 'Best First'.
Re: Anonymous sub as error handler
by Joost (Canon) on Sep 09, 2002 at 14:22 UTC
    You are not defining an anonymous sub, you are trying to call a subroutine with the name generated from the block:
    &{ # code here returns a value, # that's interpreted as the name # of the subroutine to call... }

    You need something like:

    my $subroutine = sub { # code here defines an anonymous sub }; $subroutine->( @arguments ); #call sub
    You should ask yourself what you want to do with your example: do you want to define a subroutine, call it or both?

    In your case, I would just use an unless statement:

    unless ($newSeriesSth->execute()) { # error handling }
    Anonymous subs (esp. closures) are of much more use when you need callbacks.
    -- Joost downtime n. The period during which a system is error-free and immune from user input.
Re: Anonymous sub as error handler
by dreadpiratepeter (Priest) on Sep 09, 2002 at 14:12 UTC
    Update: I fixed a typo. But more importantly, I realized from the latter responses that I was over complicating. Using an unless block to do the error-checking is much easier and more efficient than the eval.
    How about:
    eval { $newSeriesSth->execute() || die $newSeriesStr->exrrstr; }; if ($@) { if ($@ =~ /duplicate/) { print "Trying to insert duplicate row.\n"; } else { die "Unhandled errer. DBI says: $DBI::errstr"; } }

    Or you could try one of the various throw/catch implementations on cpan. (Or wait for Perl6 with built in exception support.)

    -pete
    "Pain heals. Chicks dig scars. Glory lasts forever."
Re: Anonymous sub as error handler
by broquaint (Abbot) on Sep 09, 2002 at 15:31 UTC
    The reason you get the error is that (at a guess) the if statement between the code dereference braces is run and then the result of the last statement executed is then attempted to be dereferenced, and obviously fails.

    You could achieve the execution of an anonymous sub in a few ways (there's a bunch more than listed below but they're really a variation on a theme)

    $sth->execute() || sub { ... }->(); # or $sth->execute() || &{ sub { ... } }(); # alternatively $sth->execute() || do { ... };
    Of course you'll probably just want to restructure your code as that is a much saner route.
    HTH

    _________
    broquaint

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2024-04-24 22:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found