Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Recursion and ${*digit*} variables

Reply
Thread Tools

Recursion and ${*digit*} variables

 
 
Mark
Guest
Posts: n/a
 
      08-14-2009
It appears that new ${*digit*} variables are not created when the same
subroutine is re-entered. Is this to be expected?

use strict ;
use warnings;

my $line = 'abc';
doit();
exit;

sub doit {
# local($1); # adding this doesn't appear to have an effect
$line =~ /(.)/ || die "no match";
print "bef \$1 =$1\n";

$line = substr($line,1);
doit() if length($line);

my $thing = $1; # WRONG! $1 has been changed by recursive call to
doit()

print "aft \$1 =$1\n";
}


Output:
bef $1 =a
bef $1 =b
bef $1 =c
aft $1 =c
aft $1 =c
aft $1 =c

Expected output:
bef $1 =a
bef $1 =b
bef $1 =c
aft $1 =c
aft $1 =b
aft $1 =a
 
Reply With Quote
 
 
 
 
C.DeRykus
Guest
Posts: n/a
 
      08-14-2009
On Aug 14, 11:49*am, Mark <(E-Mail Removed)> wrote:
> It appears that new ${*digit*} variables are not created when the same
> subroutine is re-entered. *Is this to be expected?
>
> use strict ;
> use warnings;
>
> my $line = 'abc';
> doit();
> exit;
>
> sub doit {
> # * local($1); *# adding this doesn't appear to have an effect
> * * $line =~ /(.)/ || die "no match";
> * * print "bef \$1 *=$1\n";
>
> * * $line = substr($line,1);
> * * doit() if length($line);
>
> * * my $thing = $1; # WRONG! $1 has been changed by recursive call to
> doit()
>
> * * print "aft \$1 *=$1\n";
>
> }
>
> Output:
> bef $1 *=a
> bef $1 *=b
> bef $1 *=c
> aft $1 *=c
> aft $1 *=c
> aft $1 *=c
>
> Expected output:
> bef $1 *=a
> bef $1 *=b
> bef $1 *=c
> aft $1 *=c
> aft $1 *=b
> aft $1 *=a


No, this came up in a recent thread. Even if a match fails
within a given scope, a previously successful backref isn't
cleared:

my $s='a';
for (1..2){
print $s=~/(.)/ ? "match:$1" : "no match:$1";
$s=substr($s,1);
}
__END__

match:a
no match:a

--
Charles DeRykus
 
Reply With Quote
 
 
 
 
Mark
Guest
Posts: n/a
 
      08-14-2009


> I would expect any sub call (that performed a successful match) to
> clobber $N. Is that not the case?


No, I don't believe that is the case. When I remove the recursion, it
works as I expect, the local $N retains its value.
For example:

use strict ;
use warnings;

my $line = 'abc';

doit();

exit;


sub doit {
$line =~ /(.)/ || die "no match";
print "bef1 \$1 =$1\n";

$line = substr($line,1);
doit2() if length($line);

print "aft1 \$1 =$1\n";
}


sub doit2 {
$line =~ /(.)/ || die "no match";
print "bef2 \$1 =$1\n";

$line = substr($line,1);

print "aft2 \$1 =$1\n";
}

Output:
bef1 $1 =a
bef2 $1 =b
aft2 $1 =b
aft1 $1 =a
 
Reply With Quote
 
C.DeRykus
Guest
Posts: n/a
 
      08-14-2009
On Aug 14, 2:46*pm, "C.DeRykus" <(E-Mail Removed)> wrote:
> On Aug 14, 11:49*am, Mark <(E-Mail Removed)> wrote:
>
>
>
> > It appears that new ${*digit*} variables are not created when the same
> > subroutine is re-entered. *Is this to be expected?

>
> > use strict ;
> > use warnings;

>
> > my $line = 'abc';
> > doit();
> > exit;

>
> > sub doit {
> > # * local($1); *# adding this doesn't appear to have an effect
> > * * $line =~ /(.)/ || die "no match";
> > * * print "bef \$1 *=$1\n";

>
> > * * $line = substr($line,1);
> > * * doit() if length($line);

>
> > * * my $thing = $1; # WRONG! $1 has been changed by recursive call to
> > doit()

>
> > * * print "aft \$1 *=$1\n";

>
> > }

>
> > Output:
> > bef $1 *=a
> > bef $1 *=b
> > bef $1 *=c
> > aft $1 *=c
> > aft $1 *=c
> > aft $1 *=c

>
> > Expected output:
> > bef $1 *=a
> > bef $1 *=b
> > bef $1 *=c
> > aft $1 *=c
> > aft $1 *=b
> > aft $1 *=a

>
> No, this came up in a recent thread. Even if a match fails
> within a given scope, a previously successful backref isn't
> cleared:
>
> my $s='a';
> for (1..2){
> * print $s=~/(.)/ ? "match:$1" : "no match:$1";
> * $s=substr($s,1);}
>
> __END__
>
> match:a
> no match:a



Just to expand that explanation a bit more:

sub doit {
$line =~ /(.)/ || die "no match";

print "bef \$1 =$1\n"; # matches succeed initially
$line = substr($line,1); # as $line gets emptied
doit() if length($line); # and doit() recurses
my $thing = $1; # WRONG! ..

print "aft \$1 =$1\n";
}

By the time the recursion starts to unwind, $line has
been drained and the match fails. Because the final "c"
matched successfully though, $1 doesn't get cleared.
So you see the trailing series of "c" printed.


--
Charles DeRykus
 
Reply With Quote
 
C.DeRykus
Guest
Posts: n/a
 
      08-14-2009
On Aug 14, 4:17*pm, "C.DeRykus" <(E-Mail Removed)> wrote:
> On Aug 14, 2:46*pm, "C.DeRykus" <(E-Mail Removed)> wrote:
>
>
>
> > On Aug 14, 11:49*am, Mark <(E-Mail Removed)> wrote:

>
> > > It appears that new ${*digit*} variables are not created when the same
> > > subroutine is re-entered. *Is this to be expected?

>
> > > use strict ;
> > > use warnings;

>
> > > my $line = 'abc';
> > > doit();
> > > exit;

>
> > > sub doit {
> > > # * local($1); *# adding this doesn't appear to have an effect
> > > * * $line =~ /(.)/ || die "no match";
> > > * * print "bef \$1 *=$1\n";

>
> > > * * $line = substr($line,1);
> > > * * doit() if length($line);

>
> > > * * my $thing = $1; # WRONG! $1 has been changed by recursive call to
> > > doit()

>
> > > * * print "aft \$1 *=$1\n";

>
> > > }

>
> > > Output:
> > > bef $1 *=a
> > > bef $1 *=b
> > > bef $1 *=c
> > > aft $1 *=c
> > > aft $1 *=c
> > > aft $1 *=c

>
> > > Expected output:
> > > bef $1 *=a
> > > bef $1 *=b
> > > bef $1 *=c
> > > aft $1 *=c
> > > aft $1 *=b
> > > aft $1 *=a

>
> > No, this came up in a recent thread. Even if a match fails
> > within a given scope, a previously successful backref isn't
> > cleared:

>
> > my $s='a';
> > for (1..2){
> > * print $s=~/(.)/ ? "match:$1" : "no match:$1";
> > * $s=substr($s,1);}

>
> > __END__

>
> > match:a
> > no match:a

>
> Just to expand that explanation a bit more:
>
> sub doit {
> * $line =~ /(.)/ || die "no match";
>
> * print "bef \$1 *=$1\n"; * *# matches succeed initially
> * $line = substr($line,1); * # as $line gets emptied
> * doit() if length($line); * # and doit() recurses
> * my $thing = $1; # WRONG! ..
>
> * print "aft \$1 *=$1\n";
>
> }
>
> By the time the recursion starts to unwind, $line has
> been drained and the match fails. Because the final "c"
> matched successfully though, $1 doesn't get cleared.
> So you see the trailing series of "c" printed.
>


No. I need to rethink that...

--
Charles DeRykus

 
Reply With Quote
 
C.DeRykus
Guest
Posts: n/a
 
      08-15-2009
On Aug 14, 4:10*pm, Mark <(E-Mail Removed)> wrote:
> > I would expect any sub call (that performed a successful match) to
> > clobber $N. Is that not the case?

>
> No, I don't believe that is the case. *When I remove the recursion, it
> works as I expect, the local $N retains its value.
> For example:
>
> use strict ;
> use warnings;
>
> my $line = 'abc';
>
> doit();
>
> exit;
>
> sub doit {
> * * $line =~ /(.)/ || die "no match";
> * * print "bef1 \$1 *=$1\n";
>
> * * $line = substr($line,1);
> * * doit2() if length($line);
>
> * * print "aft1 \$1 *=$1\n";
>
> }
>
> sub doit2 {
> * * $line =~ /(.)/ || die "no match";
> * * print "bef2 \$1 *=$1\n";
>
> * * $line = substr($line,1);
>
> * * print "aft2 \$1 *=$1\n";
>
> }
>
> Output:
> bef1 $1 *=a
> bef2 $1 *=b
> aft2 $1 *=b
> aft1 $1 *=a


Hopefully I'm not mis-firing again but doit2() would introduce
a new scope with its own set of $N matches which won't be affected
by successful matches in other scopes. But in doit()'s scope,
successful $N matches self-clobber as mentioned.

--
Charles DeRykus
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      08-15-2009
On Fri, 14 Aug 2009 11:49:39 -0700 (PDT), Mark <(E-Mail Removed)> wrote:

>It appears that new ${*digit*} variables are not created when the same
>subroutine is re-entered. Is this to be expected?
>
>use strict ;
>use warnings;
>
>my $line = 'abc';
>doit();
>exit;
>
>sub doit {
># local($1); # adding this doesn't appear to have an effect
> $line =~ /(.)/ || die "no match";
> print "bef \$1 =$1\n";
>
> $line = substr($line,1);
> doit() if length($line);
>
> my $thing = $1; # WRONG! $1 has been changed by recursive call to
>doit()
>
> print "aft \$1 =$1\n";
>}
>
>
>Output:
>bef $1 =a
>bef $1 =b
>bef $1 =c
>aft $1 =c
>aft $1 =c
>aft $1 =c
>
>Expected output:
>bef $1 =a
>bef $1 =b
>bef $1 =c
>aft $1 =c
>aft $1 =b
>aft $1 =a



Apparently there is only 1 set of N vars per scope,
looks like its set at compile time.

So you can't stack them in the way of a recursion.
This seems to hold down memory consumption and the cost
of state.

Usually, when you recurse a function, everything starts a new.
A new regular expression evaluation and gleaning results.
In that scope, the last N vars are retained, the results aren't
stacked.

The results you obtained are not faulty, nor the result of a bad match.
The last state of N vars were retained when the stack unwound.

Remember, 1 scope, 1 set of N vars.
Poor example follows.

-sln

================================================== ====
Output:

sub b - before = b
sub c - before = c
sub d - before = d
sub e - before = e(e)
sub d - before = d
sub e - before = f(f)
sub d - before = d
sub e - before = g(g)
sub d - before = d
sub e - before = h(h)

sub e - after = h(h)
sub d - after = d
sub e - after = h(g)
sub d - after = d
sub e - after = h(f)
sub d - after = d
sub e - after = h(e)
sub d - after = d
sub c - after = c
sub b - after = b

================================================== ======

use strict ;
use warnings;
my $cnt = 0;


my $regx = qr/(.)/;

$cnt = 0;
my $Estr = 'e';
b();


sub b
{
my $str = 'b';
$str =~ /$regx/;
print "sub b - before = $1\n";
c();
print "sub b - after = $1\n";
}

sub c
{
my $str = 'c';
$str =~ /$regx/;
print "sub c - before = $1\n";
d();
print "sub c - after = $1\n";
}

sub d
{
my $str = 'd';
$str =~ /$regx/;
print "sub d - before = $1\n";
e();
print "sub d - after = $1\n";
}

sub e
{
++$Estr if (++$cnt > 1);

$Estr =~ /$regx/;
my $tmp = $1;

print "sub e - before = $1($tmp)\n";

print "\n" if ($cnt >= 4);
d() if ($cnt < 4);
print "sub e - after = $1($tmp)\n";

}

 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      08-15-2009
On Fri, 14 Aug 2009 16:17:32 -0700 (PDT), "C.DeRykus" <(E-Mail Removed)> wrote:

>On Aug 14, 2:46*pm, "C.DeRykus" <(E-Mail Removed)> wrote:
>> On Aug 14, 11:49*am, Mark <(E-Mail Removed)> wrote:
>>
>>
>>
>> > It appears that new ${*digit*} variables are not created when the same
>> > subroutine is re-entered. *Is this to be expected?

>>
>> > use strict ;
>> > use warnings;

>>
>> > my $line = 'abc';
>> > doit();
>> > exit;

>>
>> > sub doit {
>> > # * local($1); *# adding this doesn't appear to have an effect
>> > * * $line =~ /(.)/ || die "no match";
>> > * * print "bef \$1 *=$1\n";

>>
>> > * * $line = substr($line,1);
>> > * * doit() if length($line);

>>
>> > * * my $thing = $1; # WRONG! $1 has been changed by recursive call to
>> > doit()

>>
>> > * * print "aft \$1 *=$1\n";

>>
>> > }

>>
>> > Output:
>> > bef $1 *=a
>> > bef $1 *=b
>> > bef $1 *=c
>> > aft $1 *=c
>> > aft $1 *=c
>> > aft $1 *=c

>>
>> > Expected output:
>> > bef $1 *=a
>> > bef $1 *=b
>> > bef $1 *=c
>> > aft $1 *=c
>> > aft $1 *=b
>> > aft $1 *=a

>>
>> No, this came up in a recent thread. Even if a match fails
>> within a given scope, a previously successful backref isn't
>> cleared:
>>
>> my $s='a';
>> for (1..2){
>> * print $s=~/(.)/ ? "match:$1" : "no match:$1";
>> * $s=substr($s,1);}
>>
>> __END__
>>
>> match:a
>> no match:a

>
>
>Just to expand that explanation a bit more:
>
>sub doit {
> $line =~ /(.)/ || die "no match";
>
> print "bef \$1 =$1\n"; # matches succeed initially
> $line = substr($line,1); # as $line gets emptied
> doit() if length($line); # and doit() recurses
> my $thing = $1; # WRONG! ..
>
> print "aft \$1 =$1\n";
>}
>
>By the time the recursion starts to unwind, $line has
>been drained and the match fails. Because the final "c"
>matched successfully though, $1 doesn't get cleared.
>So you see the trailing series of "c" printed.


Matching had nothing to do with why his $1 contained 'c'
when the stack unwound.

The reason is he keeps reenterring the same scope block.
In terms of N vars, there is only one scope block so
the N vars keep thier last state.

N var state is not stacked, it only has scope.

-sln

 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      08-15-2009
On Fri, 14 Aug 2009 18:30:51 -0700, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>On Fri, 14 Aug 2009 16:17:32 -0700 (PDT), "C.DeRykus" <(E-Mail Removed)> wrote:
>
>>On Aug 14, 2:46*pm, "C.DeRykus" <(E-Mail Removed)> wrote:
>>> On Aug 14, 11:49*am, Mark <(E-Mail Removed)> wrote:
>>>
>>>
>>>
>>> > It appears that new ${*digit*} variables are not created when the same
>>> > subroutine is re-entered. *Is this to be expected?
>>>
>>> > use strict ;
>>> > use warnings;
>>>
>>> > my $line = 'abc';
>>> > doit();
>>> > exit;
>>>
>>> > sub doit {
>>> > # * local($1); *# adding this doesn't appear to have an effect
>>> > * * $line =~ /(.)/ || die "no match";
>>> > * * print "bef \$1 *=$1\n";
>>>
>>> > * * $line = substr($line,1);
>>> > * * doit() if length($line);
>>>
>>> > * * my $thing = $1; # WRONG! $1 has been changed by recursive call to
>>> > doit()
>>>
>>> > * * print "aft \$1 *=$1\n";
>>>
>>> > }
>>>
>>> > Output:
>>> > bef $1 *=a
>>> > bef $1 *=b
>>> > bef $1 *=c
>>> > aft $1 *=c
>>> > aft $1 *=c
>>> > aft $1 *=c
>>>
>>> > Expected output:
>>> > bef $1 *=a
>>> > bef $1 *=b
>>> > bef $1 *=c
>>> > aft $1 *=c
>>> > aft $1 *=b
>>> > aft $1 *=a
>>>
>>> No, this came up in a recent thread. Even if a match fails
>>> within a given scope, a previously successful backref isn't
>>> cleared:
>>>
>>> my $s='a';
>>> for (1..2){
>>> * print $s=~/(.)/ ? "match:$1" : "no match:$1";
>>> * $s=substr($s,1);}
>>>
>>> __END__
>>>
>>> match:a
>>> no match:a

>>
>>
>>Just to expand that explanation a bit more:
>>
>>sub doit {
>> $line =~ /(.)/ || die "no match";
>>
>> print "bef \$1 =$1\n"; # matches succeed initially
>> $line = substr($line,1); # as $line gets emptied
>> doit() if length($line); # and doit() recurses
>> my $thing = $1; # WRONG! ..
>>
>> print "aft \$1 =$1\n";
>>}
>>
>>By the time the recursion starts to unwind, $line has
>>been drained and the match fails. Because the final "c"
>>matched successfully though, $1 doesn't get cleared.
>>So you see the trailing series of "c" printed.

>
>Matching had nothing to do with why his $1 contained 'c'
>when the stack unwound.
>
>The reason is he keeps reenterring the same scope block.
>In terms of N vars, there is only one scope block so
>the N vars keep thier last state.
>
>N var state is not stacked, it only has scope.
>
>-sln


Aparently, for the N vars, the scope remained the same, it
never left. Kind of makes sense.
-sln
 
Reply With Quote
 
Nathan Keel
Guest
Posts: n/a
 
      08-15-2009
(E-Mail Removed) wrote:

> Aparently, for the N vars, the scope remained the same, it
> never left. Kind of makes sense.
> -sln


Apparently you forgot how to snip huge quotes for a few word reply.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
va_arg... recursion: changing arguments and the using recursion jononanon@googlemail.com C Programming 8 04-26-2012 08:37 PM
what is difference between Class variables and Instance variables? rahul8143@gmail.com Java 10 06-06-2011 06:43 AM
Put variables into member variables or function variables? tjumail@gmail.com C++ 9 03-23-2008 04:03 PM
recursion in scripts -- global variables required? Eric Armstrong Ruby 9 07-22-2006 01:07 PM
Session Variables and Static Variables cobus.lombard@gmail.com ASP .Net 1 03-26-2006 11:05 AM



Advertisments