How can I handle error checking in Perl?

I have a Perl routine that controls error checking. There are about 10 different checks, and some of them are nested based on previous successes. Usually these are not exceptional cases when I need croak / die . In addition, as soon as an error occurs, there is no point in checking the rest of the checks.

However, I donโ€™t think Iโ€™m thinking of a neat way to solve this problem, except by using something similar to the following terrible hack:

 sub lots_of_checks { if(failcond) { goto failstate: } elsif(failcond2) { goto failstate; } #This continues on and on until... return 1; #O happy day! failstate: return 0; #Dead... } 

What I would rather do would be something like this:

 do { if(failcond) { last; } #... }; 
+1
source share
6 answers

An empty return statement is the best way to return false from Perl rather than return 0 . The last value will indeed be true in the context of the list:

 sub lots_of_checks { return if fail_condition_1; return if fail_condition_2; # ... return 1; } 
+12
source

You might want to see the following articles on exception handling in perl5:

+8
source

You absolutely can do what you prefer.

 Check: { last Check if failcond1; last Check if failcond2; success(); } 
+5
source

Why don't you use exceptions? An exception is any case when a normal code stream does not follow. Using "return" or "goto" is actually the same, just "not what you want."

(What you really want are continuations, which "return", "goto", "last" and "throw" are all special cases. Although Perl does not have a full continuation, we do have continuation exits, a href = "http://metacpan.org/pod/Continuation::Escape" rel = "nofollow noreferrer"> http://metacpan.org/pod/Continuation::Escape)

In your code example, you write:

 do { if(failcond) { last; } #... }; 

This is probably the same as:

 eval { if(failcond){ die 'failcond'; } } 

If you want to be complicated and ignore other exceptions:

 my $magic = []; eval { if(failcond){ die $magic; } } if ( $@ != $magic) { die; # rethrow } 

Or you can use the aforementioned Continuation :: Escape module. But there is no reason to ignore exceptions; it is perfectly acceptable to use them that way.

+5
source

Given your example, I will write it as follows:

 sub lots_of_checks { local $_ = shift; # You can use 'my' here in 5.10+ return if /condition1/; return if /condition2/; # etc. return 1; } 

Note the bare return instead of return 0 . This is usually better because he respects the context; the value will be undef in the scalar context and () (empty list) in the context of the list.

If you want to hold a single exit point (which is a little non-Perlish), you can do this without resorting to goto . As stated in the documentation for last :

... the block itself is semantically identical to a loop that runs once. Thus, the "last" can be used for early exit from such a block.

 sub lots_of_checks { local $_ = shift; my $all_clear; { last if /condition1/; last if /condition2/; # ... $all_clear = 1; # only set if all checks pass } return unless $all_clear; return 1; } 
+4
source

If you want to keep your single inside / separate structure, you can slightly modify the other sentences:

 sub lots_of_checks { goto failstate if failcond1; goto failstate if failcond2; # This continues on and on until... return 1; # O happy day! failstate: # Any clean up code here. return; # Dead... } 

IMO, Perl uses the "return if EXPR" operator modifier form, which makes the security sentences more readable than they are in C. When you first see this line, you know that you have a security sentence. This feature is often blackened, but in this case I love her very much.

Using goto with an operator modifier preserves clarity and reduces clutter while it preserves your only exit code style. I used this form when I had a difficult cleanup after a failed validation for the procedure.

+2
source

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


All Articles