Comme les constantes en Ruby ne sont pas destinées à être modifiées, Ruby vous décourage de les assigner dans des parties du code qui pourraient être exécutées plus d'une fois, comme à l'intérieur des méthodes.
Dans des circonstances normales, vous devriez définir la constante à l'intérieur de la classe elle-même :
class MyClass
MY_CONSTANT = "foo"
end
MyClass::MY_CONSTANT #=> "foo"
Si, pour une raison quelconque, vous avez vraiment besoin de définir une constante à l'intérieur d'une méthode (peut-être pour un certain type de métaprogrammation), vous pouvez utiliser la procédure suivante 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"
Mais encore une fois, const_set
n'est pas quelque chose que vous devriez vraiment avoir à faire dans des circonstances normales. Si vous n'êtes pas sûr de savoir si vous vraiment Si vous voulez assigner des constantes de cette manière, vous pouvez envisager l'une des alternatives suivantes :
Variables de classe
Les variables de classe se comportent comme des constantes à bien des égards. Ce sont des propriétés d'une classe, et elles sont accessibles dans les sous-classes de la classe sur laquelle elles sont définies.
La différence est que les variables de classe sont censées être modifiables, et peuvent donc être assignées à l'intérieur des méthodes sans problème.
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"
Attributs de classe
Les attributs de classe sont une sorte de "variable d'instance sur une classe". Ils se comportent un peu comme les variables de classe, sauf que leurs valeurs ne sont pas partagées avec les sous-classes.
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"
Variables d'instance
Et pour être complet, je devrais probablement mentionner que si vous avez besoin d'assigner une valeur qui ne peut être déterminée qu'après l'instanciation de votre classe, il y a de fortes chances que vous cherchiez en fait une bonne vieille variable d'instance.
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
44 votes
La constante dynamique est quelque chose comme l'eau sèche :)
52 votes
Il n'est pas dit que la constante est dynamique. Il est dit que l'affectation est dynamique.