Re: [SPOILER] Re: New Quiz: "What does this code do?" (1-December-2006)

Joshua Kronengold <[email protected]> Thu, 14 Dec 2006 10:50:54 -0600
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
Ronald J Kimball writes:
>On Thu, Dec 14, 2006 at 09:35:57AM -0600, Joshua Kronengold wrote:
>> Shlomi Fish writes:
>> >When I said that $1 may be destroyed by the param method call, he noted
>> >that $1 was locally scoped, which indeed seems to be the case. So my
>> >code should be written like that instead.
>> Wait, what?
>> 
>> This seems wrong -- since $1 is locally scoped, (not lexically
>> scoped), it -can- be technically destroyed by the param call, so you
>> don't want to do this, even if you can. (if param is written not to
>> squash $1, it's bad practice to trust in this).
>
>No, it can't be destroyed by the param call.  When the param() exits, $1 is
>restored to its previous value, because it is locally scoped.

That's not locally scoped, that's lexically scoped.  At least as a
perl-centric coder, locally scoped would seem to be associated with
"local" -- ie, dynamically scoped.

>> perl -Mstrict -e 'sub test { shift =~ /b(.*)/ and return $1 }; my 
>> $str = "abababa"; print +($str =~ /((?:ba){1,2})/ and print 
>> test($str),"\n") ? $1 : "no","\n"'
>> ababa
>> baba
>
>I'm not sure what you're trying to show with that code.

That my assumptions were wrong?  I remember "losing" $1 due to
subroutine calls with perl 5.003 or so, but clearly the implementation
has changed.


>Here's an example
>that shows that $1 is locally, not lexically, scoped:

...
>{
>  /(a)/;
>  print "$1\n";
>  foo();
...
>sub foo {
>  print "$1\n";

>If $1 were lexically scoped, the value it gets within the block wouldn't be
>visible in the subroutine, which is outside the block.

Ah.  So what you are actually saying is "Match operators localize $1"?

That's very different than "is locally scoped", and much clearer, but
I'd prefer people didn't use the latter; it's as misleading as saying
"$_ is locally scoped".

(the latter being both not true (most constructs that override $_
automatically actually alias it to something else -- which I assume
involves pushing the reference to something else onto it's stack, and
which is similar, but not identical to localization), and not
universally relied upon (see while(<>)).

>So, there's no reason not to write the code as I suggested.  :)

No, there isn't! (and in fact, $1 is also read-only, which avoids the
possibility of bad actors changing it like they can $_).

But there -is- a reason to be more careful in explaining why.

-- 
       Joshua Kronengold (mneme@(io.com, labcats.org)) |\      _,,,--,,_  ,)
--^--   "Did you know, if you increment enough, you   /,`.-'`'   -,  ;-;;'
 /\\    get an extra digit?"  "I knew," weeps Six.    |,4-  ) )-,_ ) /\     
/-\\\   "We knew. But we had forgotten."	     '---''(_/--' (_/-'