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

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

Replies are listed 'Best First'.
(tye)Re3: Functions
by tye (Sage) on Jan 30, 2001 at 02:03 UTC

    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

        It was one example of a case where the BEGIN is required. With the BEGIN, it works either way. The BEGIN block makes the code more robust. Moving the exit statement down defeats the whole purpose of that line (which is to prevent the maintainer from having to parse all of the lines between the exit and the sub main looking for hidden run-time code. It forces any run-time code to be put up top or into BEGIN blocks making it easy to find).

        Sure, it is easy to produce cases where you don't happen to call GlobalRoutine during the window between its definition and the initialization of $sub. That doesn't mean you won't get bit by it.

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