3

In this code block,

@@y = 1
class MyClass
 @@y = 2
end
p @@y # => 2

naively, it seems that @@y is in top-level scope, and it isn't the same @@y as the one in MyClass's scope. Why is @@y affected by the class MyClass definition? (why is the result 2?)

3 Answers 3

7

Let's look at this example. Here @@x in Bar is indeed separate from @@x in Foo.

class Foo
  @@x = 1
end

class Bar
  @@x = 2
end

Foo.class_variable_get(:@@x) # => 1
Bar.class_variable_get(:@@x) # => 2

But what happens if Bar is a child of Foo?

class Foo
  @@x = 1
end

class Bar < Foo
  @@x = 2
end

Foo.class_variable_get(:@@x) # => 2
Bar.class_variable_get(:@@x) # => 2

In this case, @@x is the same in both cases, and it is the one declared in Foo.

Now, back to your example:

@@y = 1
class MyClass
  @@y = 2
end
p @@y

The first line declares class variable in the root scope. Root is a special object main which is of type Object. So, essentially, you're defining a class variable on Object class. Since everything is an Object, this is how definition of MyClass also inherits @@y and is able to change it.

Sign up to request clarification or add additional context in comments.

5 Comments

Sergio, thanks very much! That is a fine answer. Here is a corollary question: @@y = 1 class MyClass end p MyClass.class_variable_get(:@@y) p MyClass.class_variables Why doesn't #class_variables show @@y?
@sploiber: Because it shows only class variables that this class owns. See the documentation: Module.class_variables
If Bar is able to change the value of @@y in its superclass Object, why doesn't Bar change the value of @@y in its superclass Foo?
@SébastienLeCallonnec: it does, look closer :)
@SergioTulentsev Darn, you're right, time to clean my glasses. (=
1

When you do

@@y = 1

you are defining it on Object. Since MyClass is a subclass of Object, it has access to it's class variables.

@@y = 1
class MyClass
  @@y = 2
end
p @@y
puts MyClass.superclass #=> Object
puts Object.class_variables #=> @@y

1 Comment

I like both, actually; yours is more complete and adds a fuller picture. But all of this helped me. Thanks.
-1

Global vars are like this:

$y = 1

and class vars are like this:

@@y = 1

So actually your using the class vars

here is a link: vars

3 Comments

There's no word "global" in the question :)
OP asked why the class vars were behaving as observed, so must have known they were class vars. The problem was not understand the nature of Ruby class var inheritance.
Dave, yes, that is right. This exchange helped me with a fuller understanding of class variables.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.