Debido a las constantes en Ruby no están destinados a ser cambiado, Ruby le desanima a las asignaciones a ellos en partes de código que podría se ejecutan más de una vez, tales como los métodos de su interior.
En circunstancias normales, debería definir la constante dentro de la propia clase:
class MyClass
MY_CONSTANT = "foo"
end
MyClass::MY_CONSTANT #=> "foo"
Si por alguna razón, aunque realmente es necesario definir una constante dentro de un método (tal vez por algún tipo de metaprogramming), puede utilizar const_set
:
class MyClass
def my_method
self.class.const_set(:MY_CONSTANT, "foo")
end
end
MyClass::MY_CONSTANT
#=> NameError: uninitialized constant MyClass::MY_CONSTANT
MyClass.new.my_method
MyClass::MY_CONSTANT #=> "foo"
Otra vez sin embargo, const_set
no es algo que realmente debería tener que recurrir a bajo circunstancias normales. Si no está seguro de si realmente quiere estar asignando a las constantes de esta manera, es posible que desee considerar una de las siguientes alternativas:
Las variables de clase
Las variables de clase se comportan como constantes en muchas maneras. Son propiedades de una clase, y están accesibles en subclases de la clase en la que están definidas.
La diferencia es que las variables de clase están destinadas a ser modificables, y por lo tanto se pueden asignar a métodos internos sin problemas.atribuye
class MyClass
def self.my_class_variable
@@my_class_variable
end
def my_method
@@my_class_variable = "foo"
end
end
class SubClass < MyClass
end
MyClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
SubClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
MyClass.new.my_method
MyClass.my_class_variable #=> "foo"
SubClass.my_class_variable #=> "foo"
Clase
Los atributos de clase son una especie de "variable de instancia de una clase". Se comportan un poco como las variables de clase, excepto que sus valores no se comparten con las subclases.
class MyClass
class << self
attr_accessor :my_class_attribute
end
def my_method
self.class.my_class_attribute = "blah"
end
end
class SubClass < MyClass
end
MyClass.my_class_attribute #=> nil
SubClass.my_class_attribute #=> nil
MyClass.new.my_method
MyClass.my_class_attribute #=> "blah"
SubClass.my_class_attribute #=> nil
SubClass.new.my_method
SubClass.my_class_attribute #=> "blah"
Las variables de instancia
Y simplemente para la corrección probablemente debería mencionar: si tiene que asignar un valor que sólo puede ser determinado después de que su clase ha creado una instancia, hay una buena probabilidad de que en realidad podría estar buscando para una simple variable de instancia antigua.
class MyClass
attr_accessor :instance_variable
def my_method
@instance_variable = "blah"
end
end
my_object = MyClass.new
my_object.instance_variable #=> nil
my_object.my_method
my_object.instance_variable #=> "blah"
MyClass.new.instance_variable #=> nil
¿Dynamic Constant es algo así como Dry Water? :) – fl00r
No dice que la constante es dinámica. Dice que la tarea es dinámica. – sepp2k