For class variables, assigning klass.foo = 'bar'
is really some syntastic sugar for calling the klass.foo=(bar)
method. But if I assign a local variable like so:
irb(main):001:0> foo = 'bar'
=> "bar"
Then to which object is this variable assigned? Does this also call a foo=
method somewhere? I would sort of expect this, because:
In Ruby, everything is an object. Every bit of information and code can be given their own properties and actions.
In my view, this would sort-of imply one (or perhaps a few) "magic" root object(s), under which everything else is defined (...but perhaps this mental image is wrong...)
I tried:
irb(main):002:0> Kernel.foo
NoMethodError: undefined method `foo' for Kernel:Module
irb(main):003:0> Object.foo
NoMethodError: undefined method `foo' for Object:Class
irb(main):004:0> self.foo
NoMethodError: undefined method `foo' for main:Object
The same applies to code such as:
def foo
a = 'bar'
puts self.a
end
foo
which gives me:
a.rb:3:in `foo': undefined method `foo' for main:Object (NoMethodError)
from foo.rb:6:in `<main>'
There are 4 kinds of variables in Ruby: local, instance, class and global.
def x
a = 1+2
end
a
is a local variable; it is not an object but a place where a reference to the object 3
is stored. It also does not need an object to be "held" in (just a local lookup table/stack somewhere deep inside the guts of the ruby interpreter).
Same for the irb
. (But see the answer from spickermann for more information on how irb
internally transfers locals from one prompt to the next.)
The quote Everything in ruby is an object
does not mean that literally everything is an object. For example, a method is not an object (although you can have an object of class Method which "points" to a method definition - the actual compiled code). A method call is not an object. A variable is not an object (though it points to an object).
First we need to clarify some things: Assigning a variable does never automatically generate a getter for that variable:
a = 1
a #=> 1
But:
a = 1
self.a
#=> raises NoMethodError, because there is no `a` getter method defined on self.
To answer your question: A local variable is defined in the current lexical scope. When you define a local variable in IRB then the scope would be main
(an instance of Object
):
# in irb
foo = 'Hello World'
self
#=> main
self.class
#=> Object < BasicObject
local_variables
#=> [:foo, ... ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With