在Ruby 1.8.6中,我可以写 class PerformableMethod < Struct.new(:object, :method, :args)
现在在Ruby 1.9.3中,抛出一个错误: superclass mismatch for class PerformableMethod
如果我将代码更改为:
class PerformableMethod
attr_accessor :object, :method_name, :args
Run Code Online (Sandbox Code Playgroud)
但为什么结构不起作用呢?
类名在1.9和2.0中也是可选的.问题是这样的:
> Struct.new(:asdf, :qwer) == Struct.new(:asdf, :qwer)
=> false
Run Code Online (Sandbox Code Playgroud)
即使您为自己提供了一个班级名称Struct:
> Struct.new("Zxcv", :asdf, :qwer) == Struct.new("Zxcv", :asdf, :qwer)
(irb):22: warning: redefining constant Struct::Zxcv
=> false
Run Code Online (Sandbox Code Playgroud)
这意味着如果您在加载或要求的文件中有此内容:
class MyClass < Struct.new(:qwer, :asdf)
def some_method
puts "blah"
end
end
Run Code Online (Sandbox Code Playgroud)
...然后,如果你再次加载它 - 可能是因为你改变了一些东西而你想在没有重新启动irb的情况下尝试它,或者你可能在开发模式下运行Rails并且它在每个请求上重新加载类 - 然后你得到异常:
TypeError: superclass mismatch for class MyClass
Run Code Online (Sandbox Code Playgroud)
...因为每次你的类定义运行时,它都会声称一个全新Struct的超类MyClass.提供类名Struct.new()无效,如第二个代码块所示; 这只是添加了一个关于重新定义常量的警告,然后无论如何都打开了类失败.
避免异常的唯一方法是Struct在你控制的地方存放一个常量,并确保在重新加载文件时不要更改该常量.
| 归档时间: |
|
| 查看次数: |
405 次 |
| 最近记录: |