-1

What's the difference between a variable that has @@ symbols and that has only one @ symbol?

For example, if I declare a variable name in a class, what's the difference between @@name, and @name?

I'd appreciate any answer that points me to the right direction or doc :)

CodingCat
  • 133
  • 1
  • 1
  • 6
  • Not sure to which point [this](https://stackoverflow.com/questions/17098000/what-is-the-difference-between-and-in-ruby) or [this](https://stackoverflow.com/questions/5890118/what-does-variable-mean-in-ruby). – Sebastián Palma Apr 12 '21 at 18:44
  • Your question could be, "What is the difference between `@@` and `@` and when should I use one rather than another?". See [this doc](https://www.ruby-lang.org/en/documentation/faq/8/) for an answer. – Cary Swoveland Apr 12 '21 at 19:02

1 Answers1

1

@ is an instance variable. It is a variable attached to a particular object. These are how you store data on an object.

class Thing
  # These two methods are basically what `attr_accessor :stuff` does.
  def stuff=(value)
    @stuff = value
  end

  def stuff
    @stuff
  end
end

f1 = Foo.new
f1.stuff = 42  # f1's @stuff is set to 42

f2 = Foo.new
f2.stuff = 23  # f2's @stuff is set to 23

p f1.stuff  # 42
p f2.stuff  # 23

@@ is a class variable. They are to be avoided because of a quirk: they're shared with all subclasses.

class Vehicle
  @@type = 'vehicle'

  def self.type
    @@type
  end
end

class Car < Vehicle
  # This is the same @@type as in Vehicle
  @@type = 'car'
end

class Plane < Vehicle
  # This is the same @@type as in Vehicle
  @@type = 'plane'
end

p Vehicle.type # plane
p Car.type  # plane
p Plane.type  # plane

Instead, use "class instance variables". Everything in Ruby is an object including classes. They are instances of Class. class Vehicle ... end is syntax sugar for Vehicle = Class.new do ... end. And like any object, they can have instance variables.

# Same as `class Vehicle` just to demonstrate.
Vehicle = Class.new do
  # This is an instance variable on the Vehicle Class object.
  # Not Vehicle.new, but just Vehicle.
  @type = 'vehicle'
  
  def self.type
    @type
  end
end

# class Plane < Vehicle
Plane = Class.new(Vehicle) do
  # This is an instance variable on the Plane Class object.
  @type = 'plane'
end

# And the sugary way.
class Car < Vehicle
  # This is an instance variable on the Car Class object.
  @type = 'car'
end

p Vehicle.type # vehicle
p Car.type  # car
p Plane.type # plane

See Class Instance Variables in Ruby and The Official Ruby FAQ for more.

Schwern
  • 153,029
  • 25
  • 195
  • 336