in reply to Re: (tye)Re: Functions
in thread Functions

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")

Replies are listed 'Best First'.
Re: (tye)Re2: Functions
by fgcr (Novice) on Jan 30, 2001 at 02:25 UTC
    Thank you. This has helped a lot.
Re: (tye)Re2: Functions
by KM (Priest) on Jan 30, 2001 at 01:45 UTC
    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

      It works fine from my tests without the BEGIN block since $sub is initialized before the compiler will get to GlobalRoutine.

      Then I guess you missed my addition last time. Here:

      #!/usr/bin/perl -w use strict; exit main( @ARGV ); { my $sub; ## BEGIN { $sub= sub { warn "Called local sub: @_\n"; }; ## } sub GlobalRoutine { &$sub( "Test" ); } } sub main { GlobalRoutine("hi"); return 0; } __END__ This produces the following: Use of uninitialized value in subroutine entry at localsub.pl line 14. Can't use string ("") as a subroutine ref while "strict refs" in use a +t localsub.pl line 14.
              - tye (but my friends call me "Tye")
        Yes? So you move the call to main below the block and you still don't need it in a BEGIN. You would squash a normal closure by doing this as well. The BEGIN isn't needed unless you design your script so it is.

        #!/usr/bin/perl -w use strict; use vars qw($sub); #exit main(); # Useless use of closure below if called like this # BEGIN block would be needed in this case. { my $time = time(); $sub = sub {time - $time}; } exit main(); # No problem, no BEGIN needed. sub main { print &$sub; sleep 2; print &$sub; return 0; }

        Cheers,
        KM