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

using the canonical "power of 2" example, move the inner routine to the end of the outer routine.

use strict; use warnings; sub print_power_of_2 { my $x = shift; my $result = power_of_2(); print "$x^2 = $result\n"; sub power_of_2 { return $x ** 2; } } print_power_of_2(5); print_power_of_2(6);

this results in the "variable not shared" run-time warning and perlcritic errors with "inner sub from being global".

if i MUST keep the location of the inner routine; then i can't do the "convert to anonymous routine" remedy.

sub print_power_of_2 { my $x = shift; my $result = power_of_2(); print "$x^2 = $result\n"; my $power_of_2 = sub { return $x ** 2; }; }

because the routine is declared after its invocation.

what alternatives do i have? thanks

Replies are listed 'Best First'.
Re: nested routines, anonymous routines and location dependency
by Joost (Canon) on Mar 04, 2008 at 22:59 UTC
    sub print_power_of_2 { my $x = shift; my $power_of_2 = sub { return $x ** 2; }; my $result = $power_of_2->(); print "$x^2 = $result\n"; }
    Note that named subroutine declarations are always evaluated before any code that call them, so the location is "irrelevant", which also means that there aren't any situations where you "must keep the location" of the declaration.

      if named subroutine declarations are evaluated bfore any invocations; then why are anonymous routine declarations not treated the same way? i tried something like a "forward declaration", where i hoped that the first declaration would reserve the name & data type in the symbol table and that the second definition would overwrite that entry in the symbol table. this failed. thanks
        Anonymous subs aren't expected to be "static"; you can create many instances of them that take different instances of the lexical environment.

        IOW direct named subroutine declarations can only bind to a static lexical environment, but anonymous subs can close over any lexical environment in play at the moment of instantiation. You can even create multiple instances of the "same" anonymous sub.

        IIRC one of the reasons for this distinction is that you can take references to named subroutines that haven't been evaluated yet. This is useful, but it comes with certain disadvantages.

        In any case, I can't think of any example where you can't move the anonymous subs to some other location to solve the problem in your original post. In general, moving the subs makes everything clearer too.