因为 Ruby 中的常量并不意味着要更改,所以 Ruby 不鼓励您在可能多次执行的代码部分(例如内部方法)中分配给它们。
一般情况下,你应该在类本身内部定义常量:
class MyClass
MY_CONSTANT = "foo"
end
MyClass::MY_CONSTANT #=> "foo"
如果出于某种原因您确实需要在方法中定义一个常量(可能用于某种类型的元编程),您可以使用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"
同样,const_set 在正常情况下并不是您真正应该求助的。如果您不确定您是否真的想要以这种方式分配给常量,您可能需要考虑以下替代方案之一:
类变量
类变量在许多方面表现得像常量。它们是类的属性,可以在定义它们的类的子类中访问。
不同之处在于类变量是可修改的,因此可以毫无问题地分配给内部方法。
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"
类属性
类属性是一种“类的实例变量”。它们的行为有点像类变量,只是它们的值不与子类共享。
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"
实例变量
为了完整起见,我可能应该提到:如果您需要分配一个只能在您的类被实例化后确定的值,那么您很有可能实际上正在寻找一个普通的旧实例变量。
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