Are there disadvantages to autodie?
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)
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.
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.
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 $fh
after 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.
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.
精彩评论