Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby class variables in metaclass

I have a ruby class like this:

class C
  @@v = 1

  class << self
    p @@v  # everything goes well here
  end
end

class << C
  # here I get an exception 
  # `singletonclass': uninitialized class variable @@v in Object (NameError)
  # from a.rb:5:in `<main>'

  p @@v
end

My question is: the exception said 'uninitialized class variable @@v in Object (NameError)', but why ruby lookups class variables in Object(main)?

It seems like ruby always lookups metaclass' class variables outside it.

like image 999
user2016971 Avatar asked Aug 31 '26 15:08

user2016971


1 Answers

You have defined the class variable @@v for the class C. We shouldn't be surprised that this:

class << C
  p @@v
end

raises an exception, because here we are dealing with the singleton class of C, for which we have not defined a class variable @@v.

The real question is, why does it work when you do it this way?

class C
  @@v = 1

  class << self
    p @@v
  end
end

The answer appears to be that, for your convenience, whenever you access the singleton of a class from inside that class, Ruby transparently gives you access to that class's class variables.

Note that this works consistently when you define methods as well, whether you use the class << self; def method_name syntax or the def self.method_name syntax:

# assuming @@v in C is 1
class C
  def self.print_v_from_inside
    p @@v
  end
end

def C.print_v_from_outside
  p @@v
end

C.print_v_from_inside
# => 1

C.print_v_from_outside
# => NameError: uninitialized class variable @@v in Object
like image 53
Wally Altman Avatar answered Sep 03 '26 06:09

Wally Altman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!