Загрузить константу из строки, как разрешено в текущей области - PullRequest
0 голосов
/ 12 февраля 2019

Скажем, у меня есть следующая структура:

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::MySubclass);str будет, следовательно, разрешен как MyApplication::MyClass.Мне нужно полностью решить эту проблему, потому что позже мне нужно использовать эту константу вне этого пространства имен.

1 Ответ

0 голосов
/ 12 февраля 2019

При разрешении константы Ruby сначала проверяет текущее вложение модулей, а затем предков самого внутреннего модуля.

Это может быть воспроизведено путем обхода Module.nesting и Module.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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...