Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Catching closures

by bduggan (Pilgrim)
on Mar 05, 2008 at 20:36 UTC ( [id://672274]=perlquestion: print w/replies, xml ) Need Help??

bduggan has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

In a mod_perl app, I execute a database transaction with a subroutine that takes a coderef as a parameter. Since closures can have bad effects and be hard to track down, I want the transaction sub to helpfully tell me when the coderef that's passed accidentally contains references to lexical variables in its original enclosing scope. I came up with
my $str = Data::Dumper->new([$coderef],['$a'])->Deparse(1); eval $str;
then see if anything goes wrong in $@.
Is there a better way?
thanks

Replies are listed 'Best First'.
Re: Catching closures
by akho (Hermit) on Mar 05, 2008 at 20:54 UTC
    Could you tell me more about problems you see with closures? I use them quite liberally and haven't had any problems. Should I be more careful?
      What the OP is refering to is the fact that under mod_perl your ordinary code get turned into a subroutine (if it is run as a registry script that is) and all of a sudden the subroutines in your code will unexpectedly close over lexical variables defined outside of their scope. This gives all kinds of strange effects such as your webpages "remembering" previous values and not resetting them.

      Closures are not bad, but if they happen unexpectedly they are quite bothersome and difficult to debug.

      CountZero

      A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

        Except that those types of closures are easy to find if you have warnings turned on.
        If the OP is referring to that, he should just use warnings and look at the error log, instead of trying to prevent all the useful uses of closures.

        For the record, I intentionally use closures in a mod_perl environment all the time, and as far as I can see there aren't any more problems with closures than with other "complex" use of references.

      I also don't see the problem. If the subroutine refers to lexicals in the enclosing scope and modifies them, no harm is done since it gets its own copy of the lexicals

      You could equally well say that assignment can have bad effects and be hard to track down.

        Well, technically it doesn't get its own copy, it shares its copy with stuff declared in the same scope:

        use strict; use warnings; sub funcs { my $a = 0; return ( sub { $a++ }, sub { $a } ); } my ( $f11, $f12 ) = funcs(); my ( $f21, $f22 ) = funcs(); print join( " ", $f11->(), $f12->(), $f22->() ), "\n"; #prints "0 1 0"

        My point was that if someone wants to change state, he should understand what he's doing. And he probably does. Preventing that is rude.

        The OP may be in some special situation, however. That's what my question was about.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://672274]
Approved by ww
Front-paged by ikegami
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (8)
As of 2024-03-28 12:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found