Nesting and syntax of nested functions

I am trying to call a perl nested recursive function, but I cannot apply the correct syntax.

Question What is the correct syntax for making a recursive call for a nested function (if nested functions should be called recursively at all)?

Answer: Pay attention to the proposed pseudocode in the accepted answer.

Here is a snippet of pseudocode:

use Scalar::Util; sub outerfunction { my $innerfunction = sub { # Do something innerfunction(); # Do other things }; Scalar::Util::weaken($innerfunction); &$innerfunction(@_); }; 

I tried calling the internal function as follows (with subsequent error messages):

 innerfunction 

Undefined routine and main :: internal function

 &innerfunction 

Undefined routine and main :: internal function

 &$innerfunction 

The global character $ innerfunction requires an explicit package name

I also tried declaring the inner function local, but I get the following:

The global character $ innerfunction requires an explicit package name

I don't have much experience with interpreted languages, so any random comment related to a memory / stack leak / corruption or other dangers with the indicated pseudo-code would be appreciated (except for system recursion restrictions).

Thanks! perl v5.10.1 runs on Linux 2.6.34.7-61.fc13.x86_64

+4
source share
2 answers

The innerfunction() syntax is only available for routines that have been installed in the character table (for example, the syntax sub NAME {...} ). You should call your inner function as $innerfunction->() or &$innerfunction() , but where you have problems, this is the definition of the lexical word $innerfunction .

When you declare a variable with my , the variable is in the scope after which ends. Therefore, you need to split the declaration:

  my $innerfunction; $innerfunction = sub { ... $innerfunction->(); ... }; 

To break a circular link using weaken , a regular template:

 use Scalar::Util; sub outer_function { my $weak_ref; $weak_ref = my $strong_ref = sub { # Do something $weak_ref->(); # Do other things }; Scalar::Util::weaken($weak_ref); return $strong_ref; }; 

So, as soon as $strong_ref goes out of scope, the routine will be garbage collected.

+14
source
 sub outer_function { local *inner_function = sub { # Do something inner_function(); # Do other things }; inner_function(); }; 

almost as good as the following, but much clearer:

 use Scalar::Util qw( weaken ); sub outer_function { my $weak_ref; my $strong_ref = sub { # Do something $weak_ref->(); # Do other things }; weaken($weak_ref = $strong_ref); # Avoid memory leak. $strong_ref->(); }; 
+4
source

Source: https://habr.com/ru/post/1400448/


All Articles