2

This part works:

 class Example1
   @@var1= "var1 in the Example1"
   def get_var1
     @@var1
   end
 end

 example1 = Example1.new
 example1.get_var1
 # => "var1 in the Example1"

but if I try eigenclass:

def example1.get_var1
  @@var1
end

example1.get_var1
# NameError: uninitialized class variable @@var1 in Object
# from (pry):128:in `get_var1'

Ruby looks @@var1 in the Object instead of the Example.

I have tested this code in the Ruby 1.9.3 and 2.0 with the same result.

Why does it happening?
The second thing, can we turn it off (so example.get_var1 won't look for class variables in the Object)?

Darek Nędza
  • 1,420
  • 1
  • 12
  • 19
  • The official term is [singleton class](http://www.ruby-doc.org/core-2.1.2/Object.html#method-i-singleton_class). – Max Jul 01 '14 at 15:37
  • 1
    @Max Thank you, you are right, however eigenclass or metaclass is widely used in Ruby community and, as for tags, `singleton` is used for Singleton pattern. So, I don't see problems here. – Darek Nędza Jul 01 '14 at 17:02
  • 1
    True, but I think those terms are largely inventions from before Ruby 1.9, when `Object#singleton_class` was added. It pains me greatly how many people I see still using `def metaclass; class << self; self; end; end` when we've had a proper name and method for it for so long. – Max Jul 01 '14 at 19:23

1 Answers1

7

It appears as though the lexical scope for class variable lookup is kind of wacky. As near as I can tell, because you're not inside the

class Example1
end

block, ruby doesn't look up @@var in your class, but rather from Object. If you want it explicitly from your class, you can do:

def example1.get_var
    self.class.class_variable_get(:@@var1)
end

I stumbled across https://www.ruby-forum.com/topic/1228428 while searching for the answer. They're talking about 1.8.7, but it appears to apply to later versions as well.

Some Guy
  • 1,481
  • 12
  • 26
  • I would agree. Singleton method definition is lexically scoped and the surrounding class is the `Object` in this example. This is the same behavior like class reopening. If you need access ancestor class variables directly just wrap the singleton definition inside parent class scope or use indirect `class_variable_get` as SomeGuy suggests. – David Unric Jul 01 '14 at 14:32