dynamic常量分配
class MyClass def mymethod MYCONSTANT = "blah" end end
给我的错误:
SyntaxError:dynamic常量赋值错误
为什么这被认为是一个dynamic常数? 我只是给它分配一个string。
你的问题是每次运行你正在给常量分配一个新值的方法。 这是不允许的,因为它使得恒定不变。 即使string的内容是相同的(就目前而言),实际的string对象本身在每次调用方法时都是不同的。 例如:
def foo p "bar".object_id end foo #=> 15779172 foo #=> 15779112
也许如果你解释了你的用例,为什么你想改变一个常量的值,我们可以帮助你更好的实现。
也许你宁愿在这个类上有一个实例variables?
class MyClass class << self attr_accessor :my_constant end def my_method self.class.my_constant = "blah" end end p MyClass.my_constant #=> nil MyClass.new.my_method p MyClass.my_constant #=> "blah"
如果你真的想在一个方法中改变一个常量的值,而你的常量是一个String或一个数组,你可以'欺骗'并使用#replace
方法使对象获得一个新的值,而不需要实际改变目的:
class MyClass BAR = "blah" def cheat(new_bar) BAR.replace new_bar end end p MyClass::BAR #=> "blah" MyClass.new.cheat "whee" p MyClass::BAR #=> "whee"
因为Ruby中的常量不会被改变,所以Ruby不鼓励把它们分配给可能会被执行多次的代码部分,比如内部方法。
在正常情况下,你应该在类中定义常量:
class MyClass MY_CONSTANT = "foo" end MyClass::MY_CONSTANT #=> "foo"
如果由于某种原因,你确实需要在一个方法内部定义一个常量(也许对于某种types的元编程),你可以使用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
并不是你真正需要的。 如果您不确定是否真的想以这种方式分配常量,则可能需要考虑以下select之一:
类variables
类variables在很多方面都像常量一样。 它们是一个类的属性,它们可以在它们定义的类的子类中访问。
不同之处在于类variables是可修改的,因此可以将其分配给内部方法而不会造成问题。
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"
类属性
类属性是一种“类上的实例variables”。 它们的行为有点像类variables,只是它们的值不与子类共享。
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
为了完整起见,我应该提一下:如果你需要分配一个只能在你的类被实例化后才能确定的值,那么很可能你正在寻找一个普通的旧实例variables。
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
在Ruby中,任何名称以大写字母开头的variables都是常量,只能赋值一次。 select其中一个替代scheme:
class MyClass MYCONSTANT = "blah" def mymethod MYCONSTANT end end class MyClass def mymethod my_constant = "blah" end end
Ruby中的常量不能在方法内部定义。 例如,请参阅此页面底部的注释
你不能用大写字母来命名一个variables,否则Ruby会把它变成一个常量,并且希望它保持它的值不变,在这种情况下,改变它的值将是一个“dynamic常量赋值错误”的错误。 小写应该没问题
class MyClass def mymethod myconstant = "blah" end end