local variable and local variable in block behave differently 
Author Message
 local variable and local variable in block behave differently

Dear Rubyists,

I am sligthly surprised by this behaviour:

if false
   b = ""
else
   1.times { b = "b" }
end

puts defined? b # => local-variable
puts b          # => b

1.times do
   if false
     a = ""
   else
     1.times { a = "a" }
   end
   puts defined? a # => local-variable(in-block)
   puts a          # => nil
end

Any reason?

Thanks

Seb.



Tue, 15 Nov 2005 20:37:06 GMT  
 local variable and local variable in block behave differently
Hi --

Quote:

> Dear Rubyists,

> I am sligthly surprised by this behaviour:

> if false
>    b = ""
> else
>    1.times { b = "b" }
> end

> puts defined? b # => local-variable
> puts b          # => b

> 1.times do
>    if false
>      a = ""
>    else
>      1.times { a = "a" }
>    end
>    puts defined? a # => local-variable(in-block)
>    puts a          # => nil
> end

> Any reason?

I'm not sure what aspect of it is surprising you, but maybe it has to
do with the fact that the assignment causes the variable to be defined
(even if, at runtime, the assignment isn't executed):

  $ ruby -e 'if false; b = 1; end; p defined?(b)'
  "local-variable"

Does that help explain it?

David

--
David Alan Black


Web:  http://pirate.shu.edu/~blackdav



Tue, 15 Nov 2005 21:13:43 GMT  
 local variable and local variable in block behave differently
Hi,

Quote:

> I'm not sure what aspect of it is surprising you, but maybe it has to
> do with the fact that the assignment causes the variable to be defined
> (even if, at runtime, the assignment isn't executed):

>   $ ruby -e 'if false; b = 1; end; p defined?(b)'
>   "local-variable"

> Does that help explain it?

> David

Sorry, I should have been more explicit. What surprises me is that in
one case, the variable a has still its value "a" wherease in the other
case, b is nil. I would have expected both cases to be the same, the
assigned value.

Seb.



Tue, 15 Nov 2005 21:24:17 GMT  
 local variable and local variable in block behave differently

Quote:

> I am sligthly surprised by this behaviour:

> if false
>   b = ""

From this point, variable "b" is defined (even though the assignment is
never executed, the interpreter has *parsed* an assignment)

Quote:
> else
>   1.times { b = "b" }
> end

This assigns to variable 'b'. Because it already exists outside of the
block, it assigns to this pre-existing variable, instead of bringing a
temporary variable into existence just for the the lifetime of the block.

Quote:
> 1.times do
>   if false
>     a = ""
>   else
>     1.times { a = "a" }
>   end
>   puts defined? a # => local-variable(in-block)
>   puts a          # => nil
> end

OK, that's weird... I would have thought that the assignment to 'a' in the
inner block would have bound to the 'a' brought into existence in the outer
block, but it hasn't.

Cheers,

Brian.



Tue, 15 Nov 2005 22:21:52 GMT  
 local variable and local variable in block behave differently

Quote:


> > I am sligthly surprised by this behaviour:

> > if false
> >   b = ""

> From this point, variable "b" is defined (even though the assignment is
> never executed, the interpreter has *parsed* an assignment)

> > else
> >   1.times { b = "b" }
> > end

> This assigns to variable 'b'. Because it already exists outside of the
> block, it assigns to this pre-existing variable, instead of bringing a
> temporary variable into existence just for the the lifetime of the block.

> > 1.times do
> >   if false
> >     a = ""
> >   else
> >     1.times { a = "a" }
> >   end
> >   puts defined? a # => local-variable(in-block)
> >   puts a          # => nil
> > end

> OK, that's weird... I would have thought that the assignment to 'a' in the
> inner block would have bound to the 'a' brought into existence in the outer
> block, but it hasn't.

my best guess is that:

  1.times do
    ####
    #### here we are in a block
    ####
    if false
      ####
      #### assignment is parsed but not executed, 'a' (block-local) is now nil
      ####
      a = ""
    else
      ####
      #### at this point, there is no 'a' in *scope*, only a block-local 'a'
      #### thus the following block creates a new block-local 'a'
      ####
      1.times { a = "a" }
    end
    ####
    #### these statements operate on the only symbol known as 'a' at this
    #### point, which happen to be the *first* block-local a.  this is not the
    #### same thing as scope, since blocks do not introduce a new scope.
    ####
    puts defined? a # => local-variable(in-block)
    puts a          # => nil
  end

this seems to confirm this:

  a = 42
  1.times do
    if false
      a = ""
    else
      1.times { a = "a" }
    end
    puts defined? a # => local-variable
    puts a          # => a
  end

since here the print statement can operate on an 'a' which is in scope.  the
first example is sort of bizarre because there never is an 'a' in scope, only
block-locals.

template = Amrita::TemplateText.new <<-html
  <ts id="correction"></ts>
html

-a
--
  ====================================
  | Ara Howard
  | NOAA Forecast Systems Laboratory
  | Information and Technology Services
  | Data Systems Group
  | R/FST 325 Broadway
  | Boulder, CO 80305-3328

  | Phone:  303-497-7238
  | Fax:    303-497-7259
  | ~ > ruby -e 'p % ^) .intern'
  ====================================



Tue, 15 Nov 2005 23:03:57 GMT  
 local variable and local variable in block behave differently

 Well, it's more

a> my best guess is that:

a>   1.times do
a>     ####
a>     #### here we are in a block
a>     ####
a>     if false
a>       ####
a>       #### assignment is parsed but not executed, 'a' (block-local) is now nil
a>       ####
a>       a = ""

 at compile time, ruby see a block local variable 'a', this variable will
 be created (at runtime) at the first assignement

a>     else
a>       ####
a>       #### at this point, there is no 'a' in *scope*, only a block-local 'a'
a>       #### thus the following block creates a new block-local 'a'
a>       ####
a>       1.times { a = "a" }

 at runtime this is the first assignement, and the variable is created
 inside the second block

a>     end
a>     ####
a>     #### these statements operate on the only symbol known as 'a' at this
a>     #### point, which happen to be the *first* block-local a.  this is not the
a>     #### same thing as scope, since blocks do not introduce a new scope.
a>     ####
a>     puts defined? a # => local-variable(in-block)

 ruby say that it has seen a local variable at compile time

a>     puts a          # => nil

 and in this block, the local variable was not assigned

Guy Decoux



Tue, 15 Nov 2005 23:20:41 GMT  
 local variable and local variable in block behave differently

Quote:

>  Well, it's more

<snip>

i was *trying* to say that... ;-)

one thing i'm fuzy on though - ruby parses/runs in one pass, so what exactly
is the distinction between the 'complile' and 'run' phases?  this is easy to
imagine for a two pass interpreter, but harder for a one pass one...

-a
--
  ====================================
  | Ara Howard
  | NOAA Forecast Systems Laboratory
  | Information and Technology Services
  | Data Systems Group
  | R/FST 325 Broadway
  | Boulder, CO 80305-3328

  | Phone:  303-497-7238
  | Fax:    303-497-7259
  | ~ > ruby -e 'p % ^) .intern'
  ====================================



Tue, 15 Nov 2005 23:27:16 GMT  
 local variable and local variable in block behave differently

Quote:


> >  Well, it's more
> <snip>

> i was *trying* to say that... ;-)

> one thing i'm fuzy on though - ruby parses/runs in one pass

I don't think so - it parses and builds an AST in a single pass, then it
walks the AST after that. Certain types of syntax error break at the parsing
stage, so nothing gets run.

But note that the *parsing* of a class or method definition does not
actually create the class or method; it is only when it is run that the
class is created. At an extreme:

   print "Do you want debugging? "
   if gets =~ /\A[Yy]/
     class Foo
       .. debug version
     end
   else
     class Foo
       .. non-debug version
     end
   end

The class definitely isn't defined until run-time.

Regards,

Brian.



Tue, 15 Nov 2005 23:39:48 GMT  
 local variable and local variable in block behave differently
Hi,

In message "Re: local variable and local variable in block behave differently"

|> 1.times do
|>   if false
|>     a = ""
|>   else
|>     1.times { a = "a" }
|>   end
|>   puts defined? a # => local-variable(in-block)
|>   puts a          # => nil
|> end
|
|OK, that's weird... I would have thought that the assignment to 'a' in the
|inner block would have bound to the 'a' brought into existence in the outer
|block, but it hasn't.

Maybe a bug.  Let me check.

                                                        matz.



Tue, 15 Nov 2005 23:43:02 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Sequence local = local variable?

2. Local variables & blocks

3. Implicit local variables for do...end blocks

4. local variables (nested, in-block, param eters, etc.)

5. Questions on block local variables

6. Local variables - lifetime and access variables [Q]

7. accessing a local variable in from a widgets -variable or -command properties

8. Beginner J questions: local variables

9. local variables in functions

10. local variables

11. Local variables in gawk?

12. timesaver scheduling templates----local variables?

 

 
Powered by phpBB® Forum Software