Are there disadvantages to autodie?
Asked Answered
D

4

16

Every now and again I see people on StackOverflow promote the use of autodie. But in the code here and elsewhere in the net I don't see autodie very often. Are there some disadvantages? Do I lose something when using autodie? (I have the idea of getting spoiled, when using autodie)

Dune answered 15/10, 2010 at 11:8 Comment(0)
A
18

The autodie documentation lists a couple of gotchas and bugs you should be aware of. However, most of those are relatively minor, and also fixable in the long run.

Other than that there are no real disadvantages, other than maybe the additional dependency when running on old perl versions. The fact that it isn't used very often yet might very well be caused by it being relatively new. Nevertheless, autodie (and even the old Fatal module) are generally a good idea.

Aronson answered 15/10, 2010 at 11:19 Comment(7)
I interpret the docs as saying that any user-defined subroutines you want to use with autodie must be declared before any call to use autodie; Seems to suggest you must declare (does that mean prototype?) any subs you want to use before useing any module, since that module may internally use autodie; -- any thoughts? Also wondering about interactions with AUTOLOAD.Manteau
That means if you want to use autodie to make one of non-builtins fatal, you'll have to either fully define it or pre-declare it first. That's not related to prototypes. The use-case for that are usually modules you have no control over, but that have the weird semantic of indicating failure by returning magic values. So all you have to do for those is load them before autodie. easy enough. For your own functions you can always just make it fail with a proper exception instead, or and possibly write a magic-retval wrapper around it, in case you have backward compatibility to consider.Aronson
AUTOLOAD is for methods, autodie is for making functions fatal.Aronson
Thanks. I wasn't aware that functions could be "pre-declared" in Perl without using a prototype, but some googling suggests use subs qw(foofunc barfunc); does just that. Is that what you meant? Also my concern is whether other modules that you load might cause problems if they use autodie;. Suppose I want to use modules A and B, and to autodie-ify f() which is defined in B.pm. I write use A; use B; use autodie qw(f);. But what if A.pm internally called use autodie;, e.g. in its import()? Does the world blow up?Manteau
Re your 2nd comment: Are you implying that autodie cannot be used with methods generally? (That seems like an arbitrary restriction.) Or just autoloaded methods? (Still undesirable, but somewhat understandable.)Manteau
use subs ... isn't usually needed to predeclare subs. You can use a sub declaration without a body. sub foo; ... later in the code ...; sub foo { ... }Abomasum
Thanks @Ven'Tatsu. Just checked in perlsub, and sure enough it's the very 1st line in the synopsis :)Manteau
S
10

The technology is mostly fine, but it's action at a distance and magical. Some people who read only sections of the code might not understand what happens since autodie is far away from the code they inspect. Since not everyone uses it and it's only become a practice recently, I suspect most people don't expect it. It's not really a big deal, but that sort of thing always seems ugly to me.

Sheffield answered 15/10, 2010 at 17:49 Comment(2)
I have some difficulties with the translation of your answer. Could you explain me the "don't expect it" part? Means expect here await? What does the "it" refer to?Dune
Many people won't know that autodie is enabled be because it's declaration is far away from the code they are looking at.Sheffield
H
5

There is a language model that follow C's function-based paradigm where all functions return a value, and it's up to the user to check for the return value. Perl is in this group. If I call a function, it is my responsibility to check whether or not that function actually returned something useful.

There is another language model that follows Java's exception-based paradigm where functions that fail return exceptions, and if the user needs to handle the exception, they must explicitly handle the exception. Most modern languages written since Java follow this exception-based approach.

Newer languages are exception-based because it handles the lazy developer problem. In C style programming languages, if a developer forgets or doesn't bother to check the exit status of a function, the program continues. In Java style programming languages, the program dies. In both cases, a developer could handle the problem of an invalid function result, it's that exception-based languages force developers to do so.

Why don't you see use autodie here? Several theories:

It's New

The autodie pragma is fairly new, and most developers don't have a good way to incorporate new knowledge in their Perl programming. For example, say has been around since 5.10, but I still see few developers use it even though it's a big improvement over print, and is simple to use. If a developer doesn't learn autodie when they initially learn Perl, they probably won't ever know about it.

There's No Try/Catch Syntax in Perl

Here's how Perl generally works:

open $fh, "<", $file;
if ( not defined $fh ) {
   ...    # What I do if `$fh` didn't get set.
}

I check the value of $fhafter my open statement (Okay, generally you check the return value of open itself and not the opened $fh, but bear with me!). The syntax is fairly simple and clean. It's easy to understand.

What if you used autodie and took an exception based approach? There's no built in try/catch statement in Perl like there is in Java. Instead, you take a semi-clumsy way of using eval:

use autodie;
my $fh;     # Got to be declared outside of the eval
eval {
    open $fh, "<", $file;
};        # Don't forget that semicolon!
if ( $@ ) {
   ...    # What I do if function "foo" doesn't return a good value...
}

Can you say yucky? I knew you could! Because $fh is lexically scoped, I have to declare it before my eval. Plus, I'm not even getting into the whole issue of $@ being a globally scoped variable!

It's Way Incomplete

Most modules and built in functions don't work with autodie which is more or less limited to IO calls, fork, system, and exec, Even here, it's incomplete: print and flock don't work with autodie. Outside of these, no other Perl builtin function work with autodie. Popping values off an empty array doesn't force my program to croak. Few modules check the status of autodie to see whether their functions or methods should croak instead of returning false values. So, the whole idea of turning Perl into an exception-based language doesn't happen.

Even places where you think autodie would work just don't. If you use File::Copy to get the copy and move commands, don't depend upon autodie to catch a bad file copy. You still need to check the return value of copy. If you use File::IO, all bets with autodie are off.

So, autodie doesn't quite live up to its bold promise of turning Perl into a more exception based programming language. For most people, it's mainly catches open statements, and most developers don't have issues with open ... or die....

I like the exception based approach to development, and I believe that all modules should croak on error by default. Force developers to handle exceptions instead of ignoring them. I write my modules and functions to croak when there are problems, and use eval to handle exceptions. Unfortunately, autodie just doesn't do a whole lot right now.

Haemolysin answered 19/8, 2014 at 16:52 Comment(1)
Your answers quite differs from "However, most of those are relatively minor, and also fixable in the long run" :) I wasn't gonna use it anyway, cause of the mystique behind its logic, but it's still nice to know now that there are actual reason not to :)Vevine
P
1

One other consideration is that autodie and utf8::all didn't play nicely together until a recent release of utf8::all. utf8::all is another convenience module that, like autodie, helps to setup Perl to do common tasks (this time unicode) automatically.

Plasmolysis answered 18/10, 2012 at 15:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.