动态解析 class 到全局范围
Dynamically resolve class to global scope
我需要将 class 的引用保存到散列中:
@hash['foo'] = bar if bar.is_a?(Class)
上面的代码在我的/lib
目录下,不是每次都自动加载的,bar
通常是自动加载的class。为了避免在 reload!
我的代码时出现 "A copy of xxx has been removed from the module tree but is still active" 错误,我试图将 bar
解析为全局范围,即:在 [=29] 之前添加 ::
=] 名称(Baz
正在变为 ::Baz
)。
我不确定如何在不将 class 转换为字符串、在 ::
前面添加 ::
,然后将其转换回class.
将常量分配给散列时,常量在分配时解析:(不是特定于散列的,这就是常量的工作方式)
hash = {}
A = 1
hash[:a] = A
#=> 1 # <- 1 is being assigned, not A
A = 2
hash[:a]
#=> 1
解决它的一种方法是存储常量的名称:
hash = {}
A = 1
hash[:a] = 'A'
#=> 'A'
并通过const_get
/ constantize
解决它:
A = 2
Object.const_get(hash[:a])
#=> 2
这也适用于嵌套常量:
hash[:pi] = 'Math::PI'
Object.const_get(hash[:pi])
#=> 3.141592653589793
如果您的对象恰好是命名的 class(或模块),您可以通过 Module#name
:
检索它的名称
hash[:lazy_enum] = Enumerator::Lazy.name
#=> "Enumerator::Lazy"
Object.const_get(hash[:lazy_enum])
#=> Enumerator::Lazy
另一种方法是使用 proc 引用其块中的常量:
hash = {}
A = 1
hash[:a] = -> { A }
#=> #<Proc:0x00007fc4ba05f510@(irb):10 (lambda)>
调用块时将解析常量:
A = 2
hash[:a].call
#=> 2
我需要将 class 的引用保存到散列中:
@hash['foo'] = bar if bar.is_a?(Class)
上面的代码在我的/lib
目录下,不是每次都自动加载的,bar
通常是自动加载的class。为了避免在 reload!
我的代码时出现 "A copy of xxx has been removed from the module tree but is still active" 错误,我试图将 bar
解析为全局范围,即:在 [=29] 之前添加 ::
=] 名称(Baz
正在变为 ::Baz
)。
我不确定如何在不将 class 转换为字符串、在 ::
前面添加 ::
,然后将其转换回class.
将常量分配给散列时,常量在分配时解析:(不是特定于散列的,这就是常量的工作方式)
hash = {}
A = 1
hash[:a] = A
#=> 1 # <- 1 is being assigned, not A
A = 2
hash[:a]
#=> 1
解决它的一种方法是存储常量的名称:
hash = {}
A = 1
hash[:a] = 'A'
#=> 'A'
并通过const_get
/ constantize
解决它:
A = 2
Object.const_get(hash[:a])
#=> 2
这也适用于嵌套常量:
hash[:pi] = 'Math::PI'
Object.const_get(hash[:pi])
#=> 3.141592653589793
如果您的对象恰好是命名的 class(或模块),您可以通过 Module#name
:
hash[:lazy_enum] = Enumerator::Lazy.name
#=> "Enumerator::Lazy"
Object.const_get(hash[:lazy_enum])
#=> Enumerator::Lazy
另一种方法是使用 proc 引用其块中的常量:
hash = {}
A = 1
hash[:a] = -> { A }
#=> #<Proc:0x00007fc4ba05f510@(irb):10 (lambda)>
调用块时将解析常量:
A = 2
hash[:a].call
#=> 2