Ну, во-первых ... действительно хорошая идея объяснить, как точно работают @@
переменные.
@@
переменные - это переменные класса, к которым можно обращаться в контексте экземпляра, например, например:
class Klass
def my_klass_variable=(str)
# self here points to an instance of Klass
@@my_klass_variable = str
end
def my_klass_variable
@@my_klass_variable
end
end
Klass.new.my_klass_variable = "Say whaat?"
# Note this is a different instance
Klass.new.my_klass_variable # => "Say whaat?"
Однако этот тип переменных также будет иметь место в следующем результате:
class OtherKlass < Klass; end
Klass.new.my_klass_variable = "Howdy"
# Note this is a different instance, and from the child class
OtherKlass.new.my_klass_variable # => "Howdy"
Действительно сумасшедшее поведение. Другой способ создания переменных класса - определение переменных экземпляра для метода, который начинается с self.
. Например:
class Klass
def self.my_class_method
@class_var = "This is a class var"
end
end
Почему @
также для переменных класса? Помните, что Klass
в этом экземпляре класса Class
, у него будут свои собственные переменные экземпляра, которые в конце будут переменными класса для экземпляров Klass
.
Klass.class # => Class
Klass.instance_of?(Class) # => true
k = Klass.new
k.class # => Klass
k.instance_of?(Klass) # => true
Это более безопасно для переменных класса (поскольку они будут иметь одну копию переменной, а не совместно используемую с дочерними классами) и будут вести себя так, как вы ожидаете, когда будете использовать пример:
module Ammunition
def self.included(base)
base.class_eval do
@ammo = [bullets] # where bullets come from any way?
end
end
def self.unload
p @ammo
end
end
class Tank
include Ammunition # Probably you meant that instead of Packagable
@ammo += [shells] # I think you meant @ammo instead of @a
end
class Airplane
include Ammunition # Probably you meant that instead of Packagable
@ammo += [missiles, photon_torpedoes] # I think you meant @ammo instead of @a
end
Этот код, на который указывают другие, не будет работать (учитывая, что нет снарядов, ракет или фоторамок), но я думаю, вы можете понять, как заставить его работать самостоятельно.