Johan Vromans wrote:

> Would the POST be executed if the open fails? Why? Why not?
> 
>        sub readit {
>             POST {
>                 close F;
>             }
>             open F, "< $f" or die;
>             scalar(<F>)
>        }

Yes, because the flow of control passed it before the exception.
POST, as I see it, means, push a reference to the code in its block
onto a list of things to do when exiting the current scope, with no
regard to GC.


 
> But I think this is getting ridiculous. $slightly_joking++; I'd
> propose a much nicer and cleaner concept:
> 
>     sub readit {
>         open F ... ;
>         prog1 {
>             scalar(<F>);
>             close F;
>         }
>     }
> 
> 'prog1' executes all expressions in the block, and returns the result
> of the first expression. Of course, we also need prog2, prog3, and so
> on ... $slightly_joking--;
> 
> All that POST and such do, is obfuscate the flow of control. I doubt
> that outweighs the small benefits.
> 
> -- Johan

do BEGIN and END obfuscate the flow of control?



       If constructors can have arbitrary names, then why not
       destructors?  Because while a constructor is explicitly
       called, a destructor is not.  Destruction happens
       automatically via Perl's garbage collection (GC) system,
       which is a quick but somewhat lazy reference-based GC
       system.  To know what to call, Perl insists that the
       destructor be named DESTROY.  Perl's notion of the right
       time to call a destructor is not well-defined currently,
       which is why your destructors should not rely on when they
       are called.

       Why is DESTROY in all caps?  Perl on occasion uses purely
       uppercase function names as a convention to indicate that
       the function will be automatically called by Perl in some
       way.  Others that are called implicitly include BEGIN,
       END, AUTOLOAD ...




The twisty-turny things you have to do in order to have cleanup
code right now prevent a subroutine that needs cleanup code from
having multiple exit points, unless the cleanup code is listed
at each one.


With POST, you explicitly declare cleanup code as soon as you see
you will need it, and you don't have to worry about your lock
getting forgotten about or your file remaining open.



        # without POST
        sub find_first_line_matching_array($\@){
                open F, shift or die "could not open: $!";
                while(<F>){
                        foreach $w (@{$_[0]}){
                                if (/$w/){
                                        close F;
                                        return $_;
        }       }       }       }

        # with POST
        sub find_first_line_matching_array($\@){
                open F, shift or die "could not open: $!";
                POST{close F};
                while(<F>){
                        foreach $w (@{$_[0]}){
                                return $_ if /$w/;
        }       }       }       

The above is a very contrived way to have multiple exit points;
but tracking $retval so you can hit your cleanup code is a drag.

Many times I've chosen to use something like C<goto have_value>
to hop down to the end of the sub, rather than repeat my
cleanup code before the return, several times, in inconvenient blocks.


POST would not be intended for flow-of-control; it is intended
to raise the code's s/n ration by abstracting the housekeeping.

Reply via email to