in reply to Functions

{ my $sub; BEGIN { $sub= sub { # ... }; } sub GlobalRoutine { &$sub( ... ); } }

Is one way to do it.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: Functions
by KM (Priest) on Jan 30, 2001 at 01:15 UTC
    You shouldn't need the BEGIN block in there. The $sub var will go out of scope at the end of the block anyways. Nice closure of a subroutine.

    Cheers,
    KM

      exit main( @ARGV ); { my $sub; BEGIN { $sub= sub { # ... }; } sub GlobalRoutine { &$sub( ... ); } } sub main { # ... }

      It is easy to put this in places where the BEGIN block becomes necessary. Some are much more subtle than this. Without the BEGIN block, $sub is declared and GlobalRoutine is compiled before $sub is initialized so it then becomes possible for GlobalRoutine to be called while $sub is still undef.

      I'm sorry that Perl doesn't have real static variables such that I have to resort to an extra empty block and doing the initialization in a BEGIN block. Note that this trick won't work if you are using mod_perl.

      FYI, since I didn't use any local variables in the anonymous subroutine, it isn't a closure in my book.

              - tye (but my friends call me "Tye")
        Thank you. This has helped a lot.
        It works fine from my tests without the BEGIN block since $sub is initialized befor the compiler will get to GlobalRoutine.

        Since $sub goes out of scope, but there is still a pointer to it which can only be accessed via GlobalRoutine, I would consider it a closure, although possibly not by the true sense of the definition. However, $sub could itself use lexical, and meet the 'definition'. I'll call it a pseudo-closure, you can call it a 'closing' if you like.

        Cheers,
        KM