@
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.