Ruby on rails Constantize引发未初始化的常量错误
我正在研究并决定通过执行以下操作,可以动态创建从StandardError继承的类:Ruby on rails Constantize引发未初始化的常量错误,ruby-on-rails,ruby,metaprogramming,Ruby On Rails,Ruby,Metaprogramming,我正在研究并决定通过执行以下操作,可以动态创建从StandardError继承的类: something = "JustForBelow" error_class = "#{something}Error".constantize error_class = StandardError.new 但我得到了一个非常奇怪的错误(在我看来),那就是: Uninitialized constant JustForBelowError 我不是正在初始化它吗 (本质上)当我尝试此操作时,会出现相同的错误
something = "JustForBelow"
error_class = "#{something}Error".constantize
error_class = StandardError.new
但我得到了一个非常奇怪的错误(在我看来),那就是:
Uninitialized constant JustForBelowError
我不是正在初始化它吗
(本质上)当我尝试此操作时,会出现相同的错误:
StandardError.const_get "#{something}Error"
# => NameError: uninitialized constant StandardError::JustForBelowClass
这感觉很奇怪,因为a)这些是超级随机的名字;没有任何冲突,并且b)我非常确定我以前使用过constantize,就像在第一个示例中一样。你知道哪里出了问题吗?如果你这样做的话,你会对它进行初始化:
class JustForBelowError < StandardError ; end
something = "JustForBelow"
error_class = "#{somestring}Error".constantize
error_class = StandardError.new
类justForbeLowerError
如果您希望能够使用
constantize
ActiveSupport的constantize
方法“访问”常量,则需要定义一个常量。它是const_-get
的一个更高级版本,它可以很好地遍历嵌套的模块结构
'blargle'.safe_constantize # => nil
'UnknownModule'.safe_constantize # => nil
'UnknownModule::Foo::Bar'.safe_constantize # => nil
要创建新错误,您需要执行以下操作:
2.0.0-p247 :013 > Object.const_set("MyNewError", Class.new(StandardError))
=> MyNewError
2.0.0-p247 :014 > MyNewError.ancestors
=> [MyNewError, StandardError, Exception, Object, Kernel, BasicObject]
在这一点上,您可以执行“MyNewError”。恒定化并返回新的类对象
编辑
还要注意的是,在第二个示例中,const_get
错误正在查找调用它的名称空间内部。在这种情况下,在StandardError
的范围内
例如,如果您的类结构如下:
module A
class B
CONSTANT = "hello world"
end
end
然后你可以通过“A::B::CONSTANT”.constantize
,或者通过Object.const_-get(“A”).const_-get(“B”).const_-get(“CONSTANT”)
来实现。同样,只做ActiveSupport更容易做到。对于任何试图找到“当类可能不存在时,我如何进行常量化”的人,有一个safe\u constantize
,如果类不存在,它将返回nil
。它本质上只是一个拯救
围绕稳定
'blargle'.safe_constantize # => nil
'UnknownModule'.safe_constantize # => nil
'UnknownModule::Foo::Bar'.safe_constantize # => nil
那么,没有办法动态定义该常数了吗?如中所示,在不知道什么字符串将取代JustForbeLowerError的情况下,从插值字符串初始化该类?等等。刚才看到上面,这似乎回答了后续的问题