Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To which object is a local variable assigned?

Tags:

ruby

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>'
like image 552
Martin Tournoij Avatar asked Dec 24 '22 08:12

Martin Tournoij


2 Answers

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).

like image 55
AnoE Avatar answered Jan 10 '23 09:01

AnoE


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, ... ]
like image 25
spickermann Avatar answered Jan 10 '23 11:01

spickermann