Ruby is a OO language, but the categories of variable it supports are a bit different from Java or C#.

In Java and C#, there are two kinds of variables, instance variables (tied to class instances, aka objects) and static variables (tied to classes).

However, in Ruby, there are three kinds of variables, instance variables, class variables, class instance variables. See original post here.

  • Instance variables are prefixed by @, and available only inside instance methods.

  • Class instance variables are prefixed by @, defined inside class directly, and available only inside class methods. The naming may sound strange, but it becomes sensible once realizing class is an object as well in Ruby.

  • Class variables are prefixed by @@, and available in both instance methods and class methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Test
@@class_variable = nil
@class_instance_variable = nil

def instance_method
@instance_variable = nil
@@class_variable = nil
end

def self.class_method
@class_instance_variable = nil
@@class_variable = nil
end
end

There’s another important difference between class variables, and class instance variables. This SO answer explains it really well: class instance variables are local to the class instance (note that class is an object as well), while class variables are shared by all classes in the hierarchy chain. It provides two snippets as well, which are reprinted below:

Class instance variables:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Parent
@things = []
def self.things
@things
end
def things
self.class.things
end
end

class Child < Parent
@things = []
end

Parent.things << :car
Child.things << :doll
mom = Parent.new
dad = Parent.new

p Parent.things #=> [:car]
p Child.things #=> [:doll]
p mom.things #=> [:car]
p dad.things #=> [:car]

Class variables:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Parent
@@things = []
def self.things
@@things
end
def things
@@things
end
end

class Child < Parent
end

Parent.things << :car
Child.things << :doll

p Parent.things #=> [:car,:doll]
p Child.things #=> [:car,:doll]

mom = Parent.new
dad = Parent.new
son1 = Child.new
son2 = Child.new
daughter = Child.new

[ mom, dad, son1, son2, daughter ].each{ |person| p person.things }
#=> [:car, :doll]
#=> [:car, :doll]
#=> [:car, :doll]
#=> [:car, :doll]
#=> [:car, :doll]