in reply to Re: nested routines, anonymous routines and location dependency
in thread nested routines, anonymous routines and location dependency

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
  • Comment on Re^2: nested routines, anonymous routines and location dependency

Replies are listed 'Best First'.
Re^3: nested routines, anonymous routines and location dependency
by Joost (Canon) on Mar 04, 2008 at 23:18 UTC
    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.

      thanks for your explanation.

      due to political reasons, the location of routine is fixed! so i did parameter passing to the inner routine.

      this silenced the run-time warning. perlcritic's error still remains, but i'll ignore it (even though it is a severity level 5!)

        due to political reasons, the location of routine is fixed!

        Sadly, you have two problems: broken code and a broken development process. I wonder to what degree explaining that the development process leads to broken code will help you fix the broken development process.

        Could you get away with the following?

        { my $shared_data; my $inner_sub; sub outer_sub { ... ... $inner_sub->(...) ... ... } $inner_sub = sub { ... $shared_data ... }; }

        That would get rid of the bug. (A named sub inside another sub in Perl is a bug in my eyes. The warning is too gentle.)

        Note that having any $shared_data makes the function non-reentrant, but you can eliminate that problem by sharing data via parameters.

        Update: no warnings 'closure'; with a comment explaining that all shared variables need to be exchanged by parameters or globals would also do the trick. But you're eliminating a very useful check.