[ruby] What does @@variable mean in Ruby?

What are Ruby variables preceded with double at signs (@@)? My understanding of a variable preceded with an at sign is that it is an instance variable, like this in PHP:

PHP version

class Person {

    public $name;

    public function setName($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

Ruby equivalent

class Person

    def set_name(name)
        @name = name
    end

    def get_name()
        @name
    end
end

What does the double at sign @@ mean, and how does it differ from a single at sign?

This question is related to ruby syntax instance-variables class-variables

The answer is


The answers are partially correct because @@ is actually a class variable which is per class hierarchy meaning it is shared by a class, its instances and its descendant classes and their instances.

class Person
  @@people = []

  def initialize
    @@people << self
  end

  def self.people
    @@people
  end
end

class Student < Person
end

class Graduate < Student
end

Person.new
Student.new

puts Graduate.people

This will output

#<Person:0x007fa70fa24870>
#<Student:0x007fa70fa24848>

So there is only one same @@variable for Person, Student and Graduate classes and all class and instance methods of these classes refer to the same variable.

There is another way of defining a class variable which is defined on a class object (Remember that each class is actually an instance of something which is actually the Class class but it is another story). You use @ notation instead of @@ but you can't access these variables from instance methods. You need to have class method wrappers.

class Person

  def initialize
    self.class.add_person self
  end

  def self.people
    @people
  end

  def self.add_person instance
    @people ||= []
    @people << instance
  end
end

class Student < Person
end

class Graduate < Student
end

Person.new
Person.new
Student.new
Student.new
Graduate.new
Graduate.new

puts Student.people.join(",")
puts Person.people.join(",")
puts Graduate.people.join(",")

Here, @people is single per class instead of class hierarchy because it is actually a variable stored on each class instance. This is the output:

#<Student:0x007f8e9d2267e8>,#<Student:0x007f8e9d21ff38>
#<Person:0x007f8e9d226158>,#<Person:0x007f8e9d226608>
#<Graduate:0x007f8e9d21fec0>,#<Graduate:0x007f8e9d21fdf8> 

One important difference is that, you cannot access these class variables (or class instance variables you can say) directly from instance methods because @people in an instance method would refer to an instance variable of that specific instance of the Person or Student or Graduate classes.

So while other answers correctly state that @myvariable (with single @ notation) is always an instance variable, it doesn't necessarily mean that it is not a single shared variable for all instances of that class.


@@ denotes a class variable, i.e. it can be inherited.

This means that if you create a subclass of that class, it will inherit the variable. So if you have a class Vehicle with the class variable @@number_of_wheels then if you create a class Car < Vehicle then it too will have the class variable @@number_of_wheels


@ and @@ in modules also work differently when a class extends or includes that module.

So given

module A
    @a = 'module'
    @@a = 'module'

    def get1
        @a          
    end     

    def get2
        @@a         
    end     

    def set1(a) 
        @a = a      
    end     

    def set2(a) 
        @@a = a     
    end     

    def self.set1(a)
        @a = a      
    end     

    def self.set2(a)
        @@a = a     
    end     
end 

Then you get the outputs below shown as comments

class X
    extend A

    puts get1.inspect # nil
    puts get2.inspect # "module"

    @a = 'class' 
    @@a = 'class' 

    puts get1.inspect # "class"
    puts get2.inspect # "module"

    set1('set')
    set2('set')

    puts get1.inspect # "set" 
    puts get2.inspect # "set" 

    A.set1('sset')
    A.set2('sset')

    puts get1.inspect # "set" 
    puts get2.inspect # "sset"
end 

class Y
    include A

    def doit
        puts get1.inspect # nil
        puts get2.inspect # "module"

        @a = 'class'
        @@a = 'class'

        puts get1.inspect # "class"
        puts get2.inspect # "class"

        set1('set')
        set2('set')

        puts get1.inspect # "set"
        puts get2.inspect # "set"

        A.set1('sset')
        A.set2('sset')

        puts get1.inspect # "set"
        puts get2.inspect # "sset"
    end
end

Y.new.doit

So use @@ in modules for variables you want common to all their uses, and use @ in modules for variables you want separate for every use context.


@ - Instance variable of a class
@@ - Class variable, also called as static variable in some cases

A class variable is a variable that is shared amongst all instances of a class. This means that only one variable value exists for all objects instantiated from this class. If one object instance changes the value of the variable, that new value will essentially change for all other object instances.

Another way of thinking of thinking of class variables is as global variables within the context of a single class. Class variables are declared by prefixing the variable name with two @ characters (@@). Class variables must be initialized at creation time


Examples related to ruby

Uninitialized Constant MessagesController Embed ruby within URL : Middleman Blog Titlecase all entries into a form_for text field Ruby - ignore "exit" in code Empty brackets '[]' appearing when using .where find_spec_for_exe': can't find gem bundler (>= 0.a) (Gem::GemNotFoundException) How to update Ruby Version 2.0.0 to the latest version in Mac OSX Yosemite? How to fix "Your Ruby version is 2.3.0, but your Gemfile specified 2.2.5" while server starting Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? How to update Ruby with Homebrew?

Examples related to syntax

What is the 'open' keyword in Swift? Check if returned value is not null and if so assign it, in one line, with one method call Inline for loop What does %>% function mean in R? R - " missing value where TRUE/FALSE needed " Printing variables in Python 3.4 How to replace multiple patterns at once with sed? What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript? How can I fix MySQL error #1064? What do >> and << mean in Python?

Examples related to instance-variables

What is an instance variable in Java? Ruby class instance variable vs. class variable Passing variables, creating instances, self, The mechanics and usage of classes: need explanation What does @@variable mean in Ruby? Ruby convert Object to Hash How do servlets work? Instantiation, sessions, shared variables and multithreading How to get instance variables in Python?

Examples related to class-variables

What is the difference between up-casting and down-casting with respect to class variable Ruby class instance variable vs. class variable What does @@variable mean in Ruby? Are static class variables possible in Python?