Dick Davies wrote:
Take this with a pinch of salt, I am on my first cup of caffeine
- I’m sure I’ll get corrected if it’s glaringly wrong. (I hope so)
val = “fem”
This defines a local variable called ‘val’ on Object
- not the same as an instance variable.
class Test
puts val
end
Test can’t see the local variable on Object, you get an error like:
in t': undefined local variable or method
val’ for #Object:0x807bcd8 (NameError)
from aaa:5
So you’d need an accessor on Object to get to it, and even then I think it’s gone
out of scope.
(This of course won’t print anything until you call Test.new either).
It’s not so much that it hasn’t gone out of scope here, so much as it is
no longer accessable from the inner scope. If I use val further on
after the class def it will work perfectly fine.
this works:
class Test
val = “fem”
puts val
end
Test.new
or
class Test
val = “A”
def info
puts val
end
end
Test.new.info
you can’t see val here because it’s not an instance variable of Test
objects, it’s a local variable of the Class Test. Even if you make it an
instance variable, and call it directly then
you have problems, because there is no accessor method defined:
rasputin@lb:tmp$ cat bbb.rb
class Test
@val = “A”
def info
puts Test.val
end
end
Test.new.info
rasputin@lb:tmp$ ruby -w bbb.rb
bbb.rb:4:in info': undefined method
val’ for Test:Class (NameError)
from bbb.rb:7
or
val = 1
def t
puts val
end
t
I think this is because val is a local variable, not an instance variable of
Object. Again, it’s gone out of scope by the time you call t().
If you replace val with @val, it prints ‘1’, which is what you’d probably expect.
Why is it none of these are allowed? All of these seem like perfectly
logical places that lexical scoping would allow. It really suprised me
that none of thse work, anyone have an explanation for this behavior?
I guess I should have qualified my statement a little better, I did
recognize that a def seems to be a hard scoping boundary, the question
was much more that I was very suprised by this, and was curious if
anyone had any insight as to WHY ruby chose to work things like this?
It suprises me much in the same way that we cannot def inside a def, it
will result in a new def at the top scope. It also suprises me in the
way that if we stick a class inside of a class instance variables will
not bubble down into the inner class.
Was this all just a sorta clever way to avoid needing to back check up
all scopes each time a variable is used?
It just goes against my general programming language intuition, it feels
singularly un-schemeish in a place I expected it to act scheme-ish, let
alone java-ish, c++ish and most other programming languages I can think
of. I’m sure I’ll get over it as it does most other things the way I
like, but it quite suprised me.
Charles Comstock