in reply to Re: parse lisp style config
in thread parse lisp style config

It seems the code uses nested named subs. Named subs don't nest in Perl as they do in some other languages. Try to avoid nesting named subs.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^3: parse lisp style config
by LanX (Saint) on Nov 28, 2024 at 12:04 UTC
    > seems the code uses nested named subs.

    I was baffled at first, but you're right, the OP wasn't using proper indentation.

    Worth noting that "newer" Perl versions have lexical subs via my sub name {...} constructs.

    See perlsub#Lexical-Subroutines

    Personally I'm still stuck to my $code_ref = sub {...} approaches.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

Re^3: parse lisp style config
by vincentaxhe (Scribe) on Nov 28, 2024 at 13:11 UTC
    nested subs provide some more abstraction ability, I use it always, and I need it, as long as perl still respect scope rule. Though I did not know on which case it can break bad.
      It can break bad exactly because of scope. The variables declared in the outer sub are not properly shared to the inner subs (or rather, they are shared only in the first run).
      #!/usr/bin/perl use strict; use warnings; sub outer { my ($x) = @_; sub inner { return $x + 1 } return inner() } print outer(12), "\n"; # 13 print outer(42), "\n"; # 13 !!

      Also, you'll get a warning:

      Variable "$x" will not stay shared at 1.pl line 9.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        I got the warning, if passed by arg, it's ok, thanks for explained the meaning for me.

      nnested subs provide some more abstraction ability

      Not in Perl.

      Whether nested or not, the following two snippets are equivalent:[1]

      sub foo { ... }
      BEGIN { *foo = sub { ... }; }

      As such,

      • Inner sub aren't scoped to outer sub.
      • It misleadingly appears the inner sub is scoped to the outer sub when they're not.
      • The inner sub can't use lexicals of the outer sub.
      • If the inner sub attempts to use lexicals of the outer sub, you get very weird and useless behaviour.
      • If the inner sub attempts to use lexicals of the outer sub, you get a warning.

      As you can see, you gain no abstraction or other benefits. Everything about it is bad.

      That said, none of this applies to lexical inner subs. This is fine:

      sub outer { ... my sub inner { ... } ... }

      1. Exception: The first has a name attached to the sub itself, while the second doesn't. This difference will affect croak and strack traces. I could have used Sub::Util's set_subname to correct this, but loading the module would introduce a new difference.
        I test to confirm it, Inner sub is not private. The only benefit may be an reminder inner sub will be only called inside.