What is the best practice if something goes wrong in Perl code?

Possible duplicates:
How can I handle error checking in Perl? What happens to exceptions in Perl?

I saw code that works as follows:

do_something($param) || warn "something went wrong\n"; 

and I also saw a code like this:

 eval { do_something_else($param); }; if( $@ ) { warn "something went wrong\n"; } 

Should I use eval / die in all of my routines? Do I have to write all my code based on materials returned from subprograms? Isn't eval 'code input (over and over) slowing me down?

+4
source share
6 answers

The eval block is not an eval string, so no, it's not slow. Using it is definitely recommended.

There are a few annoying subtleties to how this works (mostly annoying side effects of the fact that $@ is a global variable), so consider using Try :: Tiny instead of remembering all the little tricks you need to use eval .

+13
source
 do_something($param) || warn "something went wrong\n"; 

In this case, do_something is expected to return an error code if something goes wrong. Either he cannot die, or if this happens, this is really an unusual situation.

 eval { do_something_else($param); }; if( $@ ) { warn "something went wrong\n"; } 

The assumption here is that the only mechanism by which do_something_else reports something wrong is by throwing exceptions.

If do_something_else throws exceptions in truly exceptional situations and returns an error value in some others, you should also check its return value.

Using the block form of eval does not cause additional compilation at run time, so there are no serious performance flaws:

In the second form, the code in the block is analyzed only once - at the same time, the code surrounding the eval itself was analyzed and executed in the context of the current Perl program. This form is usually used to catch exceptions more efficiently than the first (see below), and also provides code verification inside BLOCK at compile time.

+6
source

Modules that warn very annoying. Either success or failure. Do not print something to the terminal, and then continue to work; my program cannot take action based on any message you type. If the program can continue to work, just print a message if you explicitly said that everything is in order. If the program cannot work, die . What is this for.

Always throw an exception if something is wrong. If you can fix this problem, fix it. If you cannot fix the problem, do not try; just throw an exception and let the other person handle it. (And if you cannot handle the exception from what you are calling, do not.)

Basically, the reason many programs are wrong is because they are trying to fix errors that they cannot. A program that knows how to clean at the first sign of a problem is easy to debug and fix. A program that works when it gets confused simply distorts the data and annoys everyone. So don’t do it. Die as soon as possible.

+6
source

Your two examples are completely different things. The first checks the value of the false return and takes some measures in response. The second checks the actual death of the called code.

You will need to decide which action is appropriate in each case. I would suggest just returning a lie in most cases. You must be explicitly die ing if you encounter such serious errors that you cannot continue (or it makes no sense to continue, but even then you can still return false).

Wrapping a block in eval {} is not the same as wrapping arbitrary code in eval "" . In the first case, the code is still parsed at compile time, and you do not incur additional overhead. You will simply catch any death of this code (but you will not have any indication as to what went wrong or how far you got into your code, except for the value that is left for you in $@ ). In the latter case, the code is interpreted as a simple string by the Perl interpreter until it is actually evaluated, so there is a certain cost when invoking the interpreter (and you lose all code verification at compile time).

By the way, the way you called eval and tested for the value of $@ is not a recommended form; for a detailed discussion of gotchas exceptions and methods in Perl see this discussion .

+5
source

The first version is very "perlish" and quite easy to understand. The only drawback of this idiom is that it is available only for short cases. If error handling requires more logic, use the second version.

+2
source

Nobody really turned to part of the β€œbest practice,” so I'll move on.

Yes, you should definitely throw an exception in your code if something goes wrong, and you should do it as soon as possible (so you limit the code that needs to be debugged to find out what causes it).

Code that does things like return undef to indicate failure is not particularly reliable, simply because people will use it without checking the undef value of returnvalue - this means that the variable they assume has something meaningful in reality, This leads to complex, difficult to debug problems, and even unexpected problems that arise later in previously running code.

A firmer approach is to write your code so that it dies if something goes wrong, and only when you need to restore it, wrap any calls in eval{ .. } (or, better, try { .. } catch { .. } from Try :: Tiny , as already mentioned). In most cases, there will be nothing meaningful that the call code can do to restore, so the call code remains simple in the general case, and you can simply assume that you get a useful value. If something goes wrong, then you will get an error message from the actual part of the code that failed, instead of quietly getting undef. If your calling code can do something to recover from failures, it can organize an exception catch and do whatever it needs.

Something worth reading is the exception classes , which are a structured way to send additional information to the calling code, and also allow you to choose which exceptions he wants to catch and which he cannot handle. You probably won't want to use them everywhere in your code, but they are useful when you have something complicated that can fail in equally complex ways and you want the failures to be restored.

+2
source

Source: https://habr.com/ru/post/1303387/


All Articles