in reply to sub fuction inside sub functioin?

Don't put named subs inside of other named subs, but anonymous subs are ok.
sub outer { my ($param) = @_; local *inner1 = sub { ... }; local *inner2 = sub { ... }; ... inner2(inner1($param)); }

Replies are listed 'Best First'.
Re^2: sub fuction inside sub functioin?
by LanX (Saint) on Dec 07, 2008 at 20:23 UTC
    hey you name them, they are not anonymous! ; )

    This trick with local is nice! 8 )

    But without trying it, I'll expect that you'll vivify global entries in the symbol table. (which are of course empty after the local scope ended)

    I'd rather prefer this construction

    my $inner1_cr=sub {...} ; $inner_cr->($param);

    Cheers Rolf

      hey you name them, they are not anonymous! ; )

      Not when its compiled, and that makes a difference.

      >perl -c -we"sub outer { my $x; sub inner { $x } inner() }" Variable "$x" will not stay shared at -e line 1. -e syntax OK >perl -c -we"sub outer { my $x; local *inner = sub { $x }; inner() }" -e syntax OK

      And yeah, it's effectively a named sub thereafter. That's a bonus.

      I'd rather prefer this construction

      I usually use inner subs for recursive functions, and my would cause a memory leak there. It also needlessly complicates the calling syntax.

      sub outer { ... my $helper; $helper = sub { # $helper references helper sub ... $helper->(); # helper sub references $helper ... }; ... }

      Cyclic reference ⇒ memory leak.

        Recursions with inner subs are a very special case! I agree this should be handeld with care, unfortunately reference counting is not the best garbage collection technique...

        but using the global namespace for an inner function is somehow dangerous. What if you call an external function within outer, that tries to call a completely different function also called inner()?

        Maybe you should better use package to choose another namespace within outer() in combination with this local *name strategie to prevent this trap!

        Cheers Rolf

        UPDATE: Well OK, at least you get a warning ...

        $\="\n"; sub inner { print "global_inner" } inner(); sub whatever { inner() } sub outer { local *inner=sub {print "inner_of_outer"}; inner(); whatever(); } outer(); __END__ Subroutine main::inner redefined at c:\perl\push.pm line 9. global_inner inner_of_outer inner_of_outer