从字符串加载常量,在当前范围内解析

问题描述 投票:2回答:1

说我有以下结构:

module Library
  class DSL
    def met(str)
      # load `str` here; for this case, `MyApplication::MyClass`
    end
  end

  class Superclass
    extend DSL
  end
end


module MyApplication
  class MySubclass < Library::Superclass
    met 'MyClass'
  end

  class MyClass
  end
end

Library::DSL#met里面我需要加载常量str,它以字符串形式提供。显然,如果我只是做Object.const_get(str)它不起作用。

我需要以某种方式在当前范围的背景下完全解决strMyApplication::MySubclass);因此,str将被解决为MyApplication::MyClass。我需要完全解决这个问题,因为稍后我需要在此命名空间之外使用此常量。

ruby const
1个回答
2
投票

在解析常量时,Ruby首先检查模块的当前嵌套,然后检查最内层模块的祖先。

这可以通过遍历Module.nestingModule.nesting.first.ancestors(按此顺序)来复制。如果模块定义了常量,我们可以通过const_get获取它的值:

class A
  class B
    def met
      str = 'C'
      mods = Module.nesting
      mods.concat(mods.first.ancestors)
      mod = mods.find { |c| c.const_defined?(str, false) }
      mod.const_get(str)
    end
  end

  class C
  end
end

A::B.new.met #=> A::C
© www.soinside.com 2019 - 2024. All rights reserved.