in reply to Re^5: sub fuction inside sub functioin?
in thread sub fuction inside sub functioin?

I'm "seriously comlaining" that local is another form of global, no matter which namespace.

There is no big point for using nested subs if they are not completely encapsulated and might interfere with external names, which you might not be able to control.

IMHO safer alternatives are:

# No Namespace Confusion! $\="\n"; sub inner { print "global_inner" } inner(); sub whatever { inner() } sub outer { { package outer; local *inner=sub {print "inner_of_outer"}; inner(); } whatever(); } outer(); __END__ global_inner inner_of_outer global_inner

or

# No Memory Leak! $\="\n"; my $inner=sub { print "global_inner" }; $inner->(); sub whatever { $inner->() } { my $inner; sub outer { $inner=sub {print "inner_of_outer"}; $inner->(); whatever(); } } outer(); __END__ global_inner inner_of_outer global_inner
I prefere the latter! Unless you plan to call outer() recursively *... ; )

Good night! Rolf

UPDATE: (*) and if you really want to do it, you have to simulate the mechanism of local for lexicals, by starting outer() with push @stack,$inner; and ending it with $inner=shift @stack

Replies are listed 'Best First'.
Re^7: sub fuction inside sub functioin?
by ikegami (Patriarch) on Dec 08, 2008 at 02:52 UTC

    I must disagree. Having two variables or functions with the same name in the same scope is a bad idea.

    There is no big point for using nested subs if they are not completely encapsulated

    Some encapsulation is better than no encapsulation. The extra complications are not needed. Even with the extra complications, it's still not completely encapsulated.

    # No Memory Leak!

    You haven't changed anything. $inner still refers to the sub. The sub still captures $inner if the helper was recursive. The potential for a memory leak hasn't changed at all. You made it more complex for no gain.Eventually, $inner will be assigned a new value and stop referring to the helper. Nevermind.

      why should a recursive call of inner() do a memory leak with a lexical but not with a packagevar?

      Cheers Rolf

        Lexicals are captured (counts as a reference), but package variables are not.

        When using a lexical var, the var refers to the helper and the helper refers to the var via its pad. A cyclic reference exists.

        When using a package var, the var refers to the helper but the helper doesn't refer to the var. It finds it via its symbol name when it's needed. No cyclic reference exists.

        And no, exiting the scope isn't sufficient to break the cycle. Seeing two references to $inner (outer's and inner's pads) when inner exits, inner creates a new SV and aliases $inner to it. The SV still exists anonymously since outer's pad still refers to it.