develooper Front page | perl.perl5.porters | Postings from May 2012

Re: [perl #7615] (if|unless) ( local ... ) not undone

Thread Previous | Thread Next
From:
Jesse Luehrs
Date:
May 31, 2012 15:07
Subject:
Re: [perl #7615] (if|unless) ( local ... ) not undone
Message ID:
20120531220743.GF4502@tozt.net
On Sun, May 27, 2012 at 11:22:45PM +0100, Dave Mitchell wrote:
> On Sat, May 26, 2012 at 06:10:39PM -0700, James E Keenan via RT wrote:
> > On Sat Sep 10 14:08:31 2005, schwern wrote:
> > > On Fri, Aug 26, 2005 at 09:06:50AM -0700, Steve Peters via RT wrote:
> > > > > $a = 10;
> > > > > if (local $a = 1){
> > > > > }
> > > > > print $a; # Should be 10, not 1
> > > 
> > > Still busted in 5.8.6 and blead.
> > > 
> > > $ bleadperl -wle '$a = 10;  if( local $a = 1 ) {}  print $a'
> > > Found = in conditional, should be == at -e line 1.
> > > 1
> > > $ bleadperl -wle '$a = 10;  if( my $a = 1 ) {}  print $a'
> > > Found = in conditional, should be == at -e line 1.
> > > 10
> > > 
> > > 
> > 
> > And still busted in 5.16.0.
> 
> The comparison to lexical vars is slightly misleading; its actually
> lexical vars which are the more broken: the scope of the visibility of the
> 'my' declaration doesn't match the scope of when the lexical is actually
> freed:
> 
>     sub DESTROY { warn "DESTROY(@_)\n" }
> 
>     {
> 	$x = 1;
> 	if (my $x = bless []) {
> 	    warn "in IF block: $x\n";
> 	}
> 	warn "exited IF block: $x\n";
>     }
>     warn "exited outer block: $x\n";
> 
>     warn "----\n";
> 
>     {
> 	$a = 1;
> 
> 	if (local $a = 2) {
> 	    warn "in IF block: $a\n";
> 	}
> 	warn "exited IF block: $a\n";
>     }
>     warn "exited outer block: $a\n";
> 
> which outputs:
> 
>     in IF block: main=ARRAY(0x235bde8)
>     exited IF block: 1
>     DESTROY(main=ARRAY(0x235bde8))
>     exited outer block: 1
>     ----
>     in IF block: 2
>     exited IF block: 2
>     exited outer block: 1
> 
> Here, the scope of when the lexical is freed and when the 'local' is
> undone, is consistently at the end of the enclosing block, which could
> arguably be viewed as correct; however the visibility of the lexical
> *declaration* is only for the inner block.

I've run into this several times in my own code, in the form of:

  if (my $foo = something()) {
      # use $foo
  }
  elsif (my $foo = something_else()) {
      # use $foo
  }

which gives a '"my" variable $foo masks earlier declaration in same scope'
warning under "use warnings". It is somewhat irritating.

-doy

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About