Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re^2: why is $1 cleared at end of an inline sub?

by perl-diddler (Chaplain)
on Sep 17, 2021 at 20:27 UTC ( [id://11136849]=note: print w/replies, xml ) Need Help??


in reply to Re: why is $1 cleared at end of an inline sub?
in thread why is $1 cleared at end of an inline sub?

Both of these answers ignored that the sub was an 'anonymous'/'inline' sub that would have access to surrounding local variables in the same scope, including regex vars.

I find it surprising that '$1' is affected in this way by an anonymous sub.

I wouldn't find it surprising that a normal sub would auto-save context to not completely disrupt callers (even though '$_' needs to be explicitly saved with local).

To re-ask, why is an inline-sub which I thought was designed to have access to local vars (in same context) restoring '$1'. If it was accessing or changing '$_1', it would access the copy of the sub it was in. I had supposed that the '$1' would stay constant until another regex and that an inline/anon sub wouldn't treat '$1' differently from '$_1'.

I was really more wondering what the rational might be for treating them differently in an anon/inline sub.

In the same way I find that '$1', and '$2' are cleared coming out of a 'do' block to be strange -- I would have thought only another regex would change them.

my $s="abcdefg";
$_=$s;
my @res=do { m{abc(de)(fg)}; };
P "nres=%s 1=%s, 2=%s", 0+@res, $1, $2;
'
nres=2 1=∄, 2=∄

Replies are listed 'Best First'.
Re^3: why is $1 cleared at end of an inline sub?
by haukex (Archbishop) on Sep 17, 2021 at 22:41 UTC
    Both of these answers ignored that the sub was an 'anonymous'/'inline' sub

    I "ignored" it because it makes no difference, a sub is a sub no matter whether it has an entry in the symbol table or not. (Update: There are small differences, e.g. how a sub call is parsed depending on when the compiler sees the definition, but that's not relevant to this thread.)

    ... that would have access to surrounding local variables in the same scope, including regex vars.

    Sorry, but that's not how dynamic scoping works. It might help to forget about lexical scope entirely for a moment, and to think of it in terms of the call stack: it's like local stores the current value of the variable onto a stack, and exiting the currently executing scope (sub, do, etc.) restores the saved value. This happens during runtime, hence the "dynamic". Also note that dynamic scoping only works for package variables, not lexicals (my).

    I had supposed that the '$1' would stay constant until another regex... I would have thought only another regex would change them.

    Yes, the implicit dynamic scoping can be little surprising like that, but once you get the hang of dynamic scoping, it should make sense. I showed with my example above why it makes sense to do it that way for regex variables.

Re^3: why is $1 cleared at end of an inline sub? (semantics anonymous vs named subs)
by LanX (Saint) on Sep 17, 2021 at 21:34 UTC
    "normal subs" are just named "anonymous subs", there is not much more difference.

    consider

    DB<7> *beyonce = sub { print "say my name, say my name" } DB<8> beyonce() say my name, say my name DB<9>

    this also works the other way round, you can read the sub-ref of a named sub and than destroy the name in the packages STASH:

    DB<21> sub kelly { print "say my name, say my name" } DB<22> $anosub = \&kelly DB<23> delete $main::{kelly} DB<24> $anosub->() say my name, say my name DB<25> kelly() Undefined subroutine &main::kelly called at (eval 34)[c:/Strawberry/pe +rl/lib/perl5db.pl:738] line 2.

    So where do you want to draw the line???

    side-note

    there are though block-compounds in Perl which can be confused with anonymous subs.

    Maybe that's your misunderstanding, if you talk about "inlined subs" °?

    for instance map-blocks are not ano-subs effecting return

    DB<19> sub tst { map { return $_ } 42..1e6 ; return "never executed" + } DB<20> p tst() 42 DB<21>

    But those map-like constructs in List::Util are implemented with ano-subs and won't allow returning from outer subs!

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

    °) what does that even mean?

Re^3: why is $1 cleared at end of an inline sub?
by choroba (Cardinal) on Sep 17, 2021 at 20:52 UTC
    The linked documentation explains it. Dynamic scope propagates inside blocks, but not outside.
    my $s = 'abcdefg'; $s =~ m{abc(de)(fg)}; my $output = do { sprintf "1=%s, 2=%s", $1, $2 }; print $output; # 1=de, 2=fg

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re^3: why is $1 cleared at end of an inline sub?
by LanX (Saint) on Sep 17, 2021 at 23:08 UTC
    maybe haukex understood your problem and you need to get acquainted with dynamic-scoping ... which is the only possible way to have limited control over global variables.

    NB: our package-vars and special vars like $1 are global. They are accessible everywhere at run-time and prone to "sabotage".

    Static aka lexical scoping is a totally different beast for my vars at compile-time.

    Try to debug a global variable which suddenly changes after you called a sub from a foreign module you just upgraded.

    And special vars are not protected by namespaces, they are all in main:: !

    That's why they are automatically localized in subs.

    Dynamic scoping was already a given in Perl4, which had no such thing like my or lexical scoping.

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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11136849]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (5)
As of 2024-03-29 10:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found