Ruby 是否可以使用较少的绑定块?
是否可以将一个块传递给一个方法,并确保该块本身没有绑定,这样它只能在另一个实例的上下文中执行(使用Ruby 是否可以使用较少的绑定块?,ruby,Ruby,是否可以将一个块传递给一个方法,并确保该块本身没有绑定,这样它只能在另一个实例的上下文中执行(使用{class/module/instance}\u eval),而不是简单地发送:call 这是一个令人振奋的例子 module M class File end end M.module_eval "File" # => M::File M.module_eval do File end # => File 我希望上面的最后一行返回M::File类,而不是:
{class/module/instance}\u 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
谢谢。我认为以后(在不同的名称空间中)不可能计算表示常量的标记(其中类和模块是特例)。常量是在第一次解析时设置的,因此,如果您有一个令牌
文件
要解析为令牌,那么它将在解析时(以及在解析的上下文中)进行评估。您所能做的最好的事情就是传递像:File
或“File”
这样的东西,它们不会被解析为常量,然后以某种方式让它参与常量的定义(例如,使用const_set
)。模块M;模块_eval do文件结束;结束
可能不是您想要的?但我想我需要看一些其他的用例来更好地理解您,并排除这种语法。不完全是这样。实际上,我有一个方法,它接受一个块,该方法首先创建一个模块(M
,在本例中),然后对其调用module\u eval
,传递给定的块。你似乎把名称空间和绑定混淆了。绑定是变量值对的状态,如x
是3
,等等。您似乎想要的不是绑定,而是将名称空间设置为特定状态。M.module\u eval“File”
有什么错?或者为什么M::File
不起作用?您对期望的答案设置了什么条件?我想看看您是如何创建模块的,以及您对它有什么处理方法-例如m=module.new
?我可以使用:File
,然后自己将其解析为我想要的任何内容。我很好奇我是否能用一个更好的语法逃脱惩罚。可能还有其他问题。当文件
标记被解析为一个常量并进行求值时(在最后),::File
和M::File
常量都存在。本例中的结果是::File
。如果我以“更标准的方式”重写相同的示例,而不动态创建类/模块并传递块(module M;class File;end;File end
),结果将是M::File
。在后一种情况下,当解析File
时,存在一个词法(封闭)范围,因此结果不同。我的问题是,在前一种情况下,我是否能得到同样的行为。