"David L. Nicol" wrote:
> 
>     sub openrecord{
>             my $counter, $RFN;
>             while( 1){
>                     -r ($RFN = &GetRecordFileName) and last
>                     ++$counter > 6 and return undef;
>             };
>             open REC, "$RFN";
>     ...
>     }

Depends on the degree of robstness you want.  The file could be
deleted during an OS context switch that occurrs between the -r
and the open.  The file should be closed, if opened, no matter
whether or not anything else fails, because some failures may
not be detected until close, and those should propagate.

Doing it all with exception handling is more robust.  Here's
a different example:

    sub AttemptWithOpenFile
    {
        my ($closure, @fileList) = @_; local (*F);
        foreach my $file (@fileList) {
            try { open F, $file; } catch { next; }
            try { &$closure(*F); } finally { close F; }
            return;
            }
        throw Error => "Can't open any file.";
        }

Using exceptions instead of return codes is quite natural, once
you get used to it.

 1. Wherever you previously would have C<return undef> or some
    other special return code, or a pass-by-reference value, to
    indicate the failure of a subroutine or function, instead
    use C<throw Error>.

 2. Wherever you previously would have written

        $x = foo();  defined $x or return undef;

    to propagate an error from a callee back to your caller,
    you can just write $x = foo(); because unhandled exceptions
    automatically propagate.

 3. Wherever you previously would have written the equivalent of

        $x = foo();
        unless (defined $x) {
            # do something about error
            return undef;
            }

    you can now write

        try { $x = foo(); }
        catch {
            # do something about error
            }

 4. Wherever you previously would have ignored an error in order
    to allow you to restore invariants or enforce postconditions,
    and then C<return undef> to propagate the error, like this:

        $x = foo();
        close F;
        defined $x or return undef;

    you can now write

        try     { foo();   }
        finally { close F; }

Yours, &c, Tony Olekshy

Reply via email to