用于临时修改(核心)Ruby模块的库
我曾经遇到过一个Ruby库(我不确定它是否打包成gem),它允许您方便地对Ruby模块进行临时修改。这些修改仅在“with”声明中执行的块内有效,如:用于临时修改(核心)Ruby模块的库,ruby,metaprogramming,gem,Ruby,Metaprogramming,Gem,我曾经遇到过一个Ruby库(我不确定它是否打包成gem),它允许您方便地对Ruby模块进行临时修改。这些修改仅在“with”声明中执行的块内有效,如: with(modifications) do [interesting stuff requiring the modifications] end 它确保了你不需要为了在某些地方做一些特别的事情而永久污染(核心)模块 作为我想做的一个具体示例:我想在Fixnum上定义一个“in”方法,以便内部DSL的用户可以键入: if value.in
with(modifications) do
[interesting stuff requiring the modifications]
end
它确保了你不需要为了在某些地方做一些特别的事情而永久污染(核心)模块
作为我想做的一个具体示例:我想在Fixnum上定义一个“in”方法,以便内部DSL的用户可以键入:
if value.in? [12, 16, 27, 28]
[do something interesting]
end
我会用“with”方法来包装DSL评估,这样我就不必用它来污染Fixnum了?方法。我知道这不是很难做到,但可能有一些黑暗的角落,我有一个印象,这个图书馆是非常方便的目的
有人知道我要找的这个图书馆的名字吗?我似乎记得它有点像“plusplus”,但谷歌没有给我任何东西。嗯。。这听起来像是对Ruby 2中可能包含的内容的建议。
有很多方法替换方法(alias_方法、模块包含等),因此我提供了一个抽象代码:
def with_modification
replace_method # for instance, alias_method
yield
replace_method_back
end
它会起作用的。当然,您可以通过提供您想要更改的内容的描述来增强此DSL,以使此方法更灵活,这完全取决于您。我终于找到了答案:答案是。不幸的是,这只是一个概念的证明,并没有多少成果。它的工作原理是将Ruby解析为AST,破坏树并将结果转换回Ruby。这当然是难以置信的强大,但raganwald从来没有考虑过引入通用工具来实现特定的损坏,用他自己的话来说,创建一个新的工具是“痛苦的”
在字符串上实现
in?
方法意味着在AST中搜索表示在字符串上调用in?
的特定S表达式,并将其转换为不同的方法调用;可能是本地命名空间中的?(字符串,args)中的。这很快就变成了静态类型检查的问题,以免您将?
中的每一个解释为?
中的一个字符串。一个简单的实现当然不难,但在您知道之前,您将通过正确处理名称冲突、异常处理和其他不成问题的复杂情况来扩展它,一开始甚至很明显。虽然很有趣,但当我确信我曾经见过一个在提供此功能方面已经相当成熟的库时,这是在浪费我的雇主的时间。这已经被打破了,回购协议也没有启动。但“重写”确实有一个,而且仍然是一个,尽管最后一次更新是在2008年7月18日。