从字符串加载常量,如当前作用域中所解析

时间:2019-02-12 14:02:24

标签: ruby const

说我具有以下结构:

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),那是行不通的。

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

1 个答案:

答案 0 :(得分: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