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

autodie with non-builtins

by Anonymous Monk
on Feb 17, 2009 at 00:20 UTC ( #744246=perlquestion: print w/replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

autodie has been recommended to me as replacement for Fatal. It doesn't seem to work with custom subs. Help!
$ perl -E' use File::Copy qw(mv); use Fatal qw(mv); say mv q(/tmp/foo), q(/tmp/bar); ' Can't mv(/tmp/foo, /tmp/bar), $! is "No such file or directory" at (ev +al 3) line 4 main::__ANON__('/tmp/foo', '/tmp/bar') called at -e line 1 $ perl -E' use File::Copy qw(mv); use autodie qw(mv); say mv q(/tmp/foo), q(/tmp/bar); ' 0

Replies are listed 'Best First'.
Re: autodie with non-builtins
by Anonymous Monk on Feb 17, 2009 at 02:39 UTC
    All File::Copy functions return 1 on success, 0 on failure. autodie appears to expects functions to return undef on failure. Example
    C:\strawberry>perl -E "sub moon{rand;0}; use autodie q,moon,; say moon +;" 0 C:\strawberry>perl -E "sub moon{rand;return}; use autodie q,moon,; say + moon;" Can't moon(): at -e line 1 C:\strawberry>perl -E "sub moon{rand;undef}; use autodie q,moon,; say +moon;" Can't moon(): at -e line 1 C:\strawberry>perl -E "sub moon{rand;0}; use Fatal q,moon,; say moon;" Can't moon(), $! is "" at (eval 1) line 4 main::__ANON__() called at -e line 1 C:\strawberry>perl -E "sub moon{rand;return}; use Fatal q,moon,; say m +oon;" Can't moon(), $! is "" at (eval 1) line 4 main::__ANON__() called at -e line 1 C:\strawberry>perl -E "sub moon{rand;undef}; use Fatal q,moon,; say mo +on;" Can't moon(), $! is "" at (eval 1) line 4 main::__ANON__() called at -e line 1 C:\strawberry>
    You should report this, at the very least it is a documentation bug.
Re: autodie with non-builtins
by pjf (Curate) on Feb 17, 2009 at 11:06 UTC

    Okay, I've done my research. It looks like autodie won't trigger when used with a user-defined sub if and only if that sub is called in array context, and it returns something other than an empty list/undefined to indicate failure.

    The reasons for this is that autodie has to make assumptions about user-defined functions, including those from modules such as File::Copy. It always considers an undefined value to indicate failure in scalar context, and it also considers a list consisting of a single undefined a failure, due to the large amount of code that does a return undef regardless of context.

    The bug lies in how it handles the value zero. Presently (as of 1.998) it considers any scalar false to be a failure, on the assumption that foo() or die is a common idiom for checking errors. It doesn't consider an array consisting of a single (defined) false value to be an error, since it's quite conceivable that a function that routinely returns a list could return this as valid data.

    This behaviour may not be correct, but it's rather late on my side of the world, and a week of international travel has left me short on sleep. As such, I'll be examining it in more detail in the morning.

    In the meantime, if you use mv (or any other File::Copy subroutine) in void context (ie, without say), then it should work just fine with autodie.

Re: autodie with non-builtins
by pjf (Curate) on Feb 17, 2009 at 10:16 UTC

    How very strange! If you remove the 'say', thereby putting mv into a void context, it throws an error just fine. autodie should never care about context, but clearly here it does.

    This looks like a genuine bug. Luckily, I also happen to be the author autodie, so I'm investigating now. I'll repost when I have a fix available.

Re: autodie with non-builtins
by pjf (Curate) on Feb 21, 2009 at 03:02 UTC

    Just a quick update to say that the next release of autodie will not only do-the-right-thing for File::Copy subroutines, but will also provide a hinting mechanism to allow you to tweak autodie's behaviour for modules it doesn't know about. Hints need only be provided once, at compile time, and usually in a separate piece of code, so the core interface remains nice and clean.

    The exact interface is still being worked upon, and may take a couple of days, depending upon how quickly I'm able to shift a rather large amount of tax paperwork. (One of the many joys of running a small business.)

    All the best,

Re: autodie with non-builtins
by Bloodnok (Vicar) on Feb 17, 2009 at 11:00 UTC
    I have to say that, in a test harness, the following works (a little too well:-) for me...
    use Test::More; use Test::Exception; use autodie qw/use_ok require_ok throws_ok lives_ok/; . . .

    By a little too well, I mean that it insists on finding bugs I thought I'd fixed aeons ago - long live Test::* and all who sail in her!!

    A user level that continues to overstate my experience :-))

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://744246]
Approved by almut
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (4)
As of 2017-09-26 02:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (291 votes). Check out past polls.

    Notices?