Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re^2: 'Dynamic scoping' of capture variables ($1, $2, etc.)

by nvivek (Vicar)
on Dec 18, 2012 at 12:30 UTC ( [id://1009352]=note: print w/replies, xml ) Need Help??


in reply to Re: 'Dynamic scoping' of capture variables ($1, $2, etc.)
in thread 'Dynamic scoping' of capture variables ($1, $2, etc.)

For clear definition, as $_ value got changed in every recursive call of R() function, $1 value also got changed and in return of every recursive call, the last changed value available and that is the reason for getting '1' 5 times in $1. For better understanding, here below I have shown how that recursive calls and values of $_ and $1 will be.

Initial ( First ) callback of R() function:
$_='x55x666x7777x1x'; $_=undefined;
Inside code, after evaluating s/(\d+)// ? $1 + R() : 0;
$1=55; #immediately after executing s// command
 Second callback of R():
 $_='xx666x7777x1x'; $1=55;
 Inside code, after evaluating s/(\d+)// ? $1 + R() : 0;
 $1=666; #immediately after executing s// command
  Third callback of R():
  $_='xxx7777x1x'; $1=666;
  Inside code, after evaluating s/(\d+)// ? $1 + R() : 0;
  $1=7777; #immediately after executing s// command
   Fourth callback of R():
   $_='xxxx1x'; $1=7777;
   Inside code, after evaluating s/(\d+)// ? $1 + R() : 0;
   $1=1; #immediately after executing s// command
    Fifth callback of R():
    $_='xxxxx'; $1=1;
    Inside code, after evaluating s/(\d+)// ? $1 + R() : 0;
    # no callback executed as ( there are no digits ) pattern not matched
    $1=undefined; #immediately after executing s// command
    # after prints 'xxxxx' and '1' for fifth callback
   # after prints 'xxxxx' and '1' for fourth callback
  # after prints 'xxxxx' and '1' for third callback
 # after prints 'xxxxx' and '1' for second callback
# after prints 'xxxxx' and '1' for first callback


Kindly regret me for format. I unable to get exact stack of recursive calls for presentation.

Replies are listed 'Best First'.
Re^3: 'Dynamic scoping' of capture variables ($1, $2, etc.)
by moritz (Cardinal) on Dec 18, 2012 at 14:22 UTC

    It's a good guess, because there is a the fact that $1 points into the original string, and can change when the original string changes. But it's not the source of the confusion here.

    You can see that by changing the original code to use m/(\d+)/g instead of s/(\d+)//, thus not modifying the original string at all:

    sub R { printf qq{before: \$_ is '$_'}; printf qq{ \$1 is %s \n}, defined($1) ? qq{'$1'} : 'undefined'; m/(\d+)/g ? $1 + R() : 0; printf qq{after: \$_ is '$_'}; printf qq{ \$1 is %s \n}, defined($1) ? qq{'$1'} : 'undefined'; } $_ = 'a81b2d34c1'; R(); __END__ before: $_ is 'a81b2d34c1' $1 is undefined before: $_ is 'a81b2d34c1' $1 is '81' before: $_ is 'a81b2d34c1' $1 is '2' before: $_ is 'a81b2d34c1' $1 is '34' before: $_ is 'a81b2d34c1' $1 is '1' after: $_ is 'a81b2d34c1' $1 is '1' after: $_ is 'a81b2d34c1' $1 is '1' after: $_ is 'a81b2d34c1' $1 is '1' after: $_ is 'a81b2d34c1' $1 is '1' after: $_ is 'a81b2d34c1' $1 is '1'

    Let me repeat what I wrote earlier, but hopefully a bit clearer this time: There is only one variable $1. The first call to m/()/ or s/()// creates the dynamic variable $1, and all subsequent calls modify the existing variable $1. Since there is no mechanism for resetting $1 to a previous value, you can see the last value of $1 in all stack frames that have access to it.

      Thanks for your explanation Moritz. I meant $1 value got changed similar to $_ value for better understanding. I know that $_ value getting changed due to substitute operator replaces matched digits to null string. I have a doubt in your example, how $1 value getting changed every recursive call. As per your code, your m// expression will match first digits ( 55 ) at all time as per my understanding. Of course, when I checked the code, it gives $1 value as 55, 666, 7777 and 1 respectively. Kindly give me some detail about it.
        As per your code, your m// expression will match first digits ( 55 ) at all time as per my understanding

        No, because I used m/../g in scalar context, which remembers the previous match position in pos, and then always returns the next match during subsequent calls.

        Maybe you are more familiar with it in this idiom:

        use 5.010; $_ = 'a123b45c6'; while (m/(\d+)/g) { say $1; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1009352]
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-28 12:18 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found