3

ブロックをメソッドに渡し、ブロック自体にバインディングがないことを確認して、{class/module/instance}_eval単に送信するのではなく、別のインスタンスのコンテキストでのみ (を使用して)実行できるようにすることはでき:callますか?

ここに動機付けの例があります

module M
  class File
  end  
end  
M.module_eval "File"      # => M::File
M.module_eval do File end # => File

M::File上記の最後の行で、の代わりにクラスを返すようにしたいと思い::Fileます。

心に留めておくべきもう 1 つの点は、私の具体的なアプリケーションでは、モジュールMが動的に (メソッド呼び出し内で) 作成されるのに対し、静的に (上記のように Ruby ファイル内で) 作成されることです。実際の動作は次のとおりです。

def create_module(name, &block)
  mod = Module.new
  Object.send :const_set name, mod
  mod.module_eval &block
end

create_module :M do
  file_cls = Class.new
  M.send :const_set, :File, file_cls
  File # => ::File (and I would like M::File)
end

ありがとう。

4

1 に答える 1

4

I think it is impossible to evaluate a token representing a constant (of which classes and modules are special case) later (within a different namespace). Constants are set the first time they are parsed, so if you have a token File to be parsed as a token, it will be evaluated as such at to moment of (and in the context of) parsing. The best you can do is pass something like :File or "File", which are not parsed as a constant, and somehow have it later participate in the definition of a constant (for example, using const_set).

于 2013-09-13T13:40:05.103 に答える