我曾遇到一个Ruby库(我不确定它是否曾被打包为gem),它允许您方便地对Ruby模块应用临时修改。这些修改仅在“with”声明中执行的块内有效,如:
with(modifications) do
[interesting stuff requiring the modifications]
end
它确保您不需要永久污染(核心)模块,只是为了在某些地方做一些特殊的事情。
作为我想做的一个具体例子:我想定义一个'in?' Fixnum上的方法,因此内部DSL的用户可以键入:
if value.in? [12, 16, 27, 28]
[do something interesting]
end
我会用'with'方法包装DSL评估,我不需要用这个来污染Fixnum吗?方法。我知道这不是很难做,但可能有一些黑暗的角落,我觉得这个图书馆非常方便。
有谁知道我要找的这个图书馆的名字?我似乎记得它有点像'plusplus',但Google并没有给我任何东西。
答案 0 :(得分:1)
嗯..这听起来像是Ruby 2中可能包含的内容的提案。 http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/
答案 1 :(得分:1)
我终于找到了答案:Rewrite gem by raganwald。不幸的是,它只是一个概念证明,并没有太大的成果。它的工作原理是将Ruby解析为AST,修改树并将结果转换回Ruby。这当然是非常强大的,但raganwald从来没有引入一般工具来实现特定的管理,而用自己的话来说,创建一个新的工具就是“折磨”。
在String上实现in?
方法意味着在AST中搜索表示在String上调用in?
并将其转换为其他方法调用的特定S表达式;可能是本地命名空间中的in?(string, args)
。这很快就会变成静态类型检查的问题,以免您将每个in?
解释为String#in?
。
答案 2 :(得分:0)
接近了很多方法替换(alias_method,模块包含等),所以我提供了一个抽象代码:
def with_modification
replace_method # for instance, alias_method
yield
replace_method_back
end
它会起作用。当然,您可以通过提供您想要更改的内容的描述来增强此DSL,以使此方法变得灵活,这完全取决于您。