是否可以使用无约束块?

时间:2013-09-13 12:26:31

标签: ruby

是否可以将块传递给方法,并确保该块本身没有绑定,因此它只能在另一个实例的上下文中执行(使用{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

要记住的另一件事是,在我的具体应用程序中,模块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

感谢。

1 个答案:

答案 0 :(得分:4)

我认为以后(在不同的命名空间内)不可能评估表示常量(其中的类和模块是特殊情况)的标记。常量在第一次被解析时设置,因此如果您将令牌File解析为令牌,则在解析时(以及在上下文中)将对其进行求值。您可以做的最好的事情是传递:File"File"之类的东西,这些东西不会被解析为常量,并且以后会以某种方式让它参与常量的定义(例如,使用{{1} })。