我对Ruby还是个新手,基本上只是在读完库珀的书后写了我的第一个微程序。我被指出要避免猴子补丁,但问题是我不知道有什么替代方法可以实现同样的行为。基本上,我想添加一个新的方法,每个字符串对象都可以访问。猴子补丁的明显方法是:
class String
def do_magic
...magic...
end
end
我记得有一种方法可以使用String.send,但是我不记得它是怎么做的,也不记得我是在哪里读到它的。谁能指出任何替代方法,让我仍然可以使用String类和子对象的方法?
7条答案
按热度按时间50pmv0ei1#
任何其他的方法都只是猴子修补的语法上的一个更笨拙的方法。有一些方法涉及
send
和eval
以及各种各样的东西,但是 * 为什么 *?继续用显而易见的方法来做吧。在大型项目中或者当您有依赖项时,您需要小心猴子修补,因为当几只手都在同一个地方乱操作时,你可能会遇到冲突。这并不意味着寻找一种替代语法来完成同样的事情--这意味着当你所做的更改可能会影响不属于你的代码时,要小心。在你的特定情况下,这可能不是一个问题。这只是一些可能需要在更大的项目中解决的问题。
Ruby中的一种替代方法是可以向单个对象添加方法。
5rgfhyps2#
如果你想添加一个每个字符串对象都可以访问的新方法,那么按照你已有的方法去做就是如何完成它。
一个好的做法是把你的核心对象扩展放在一个单独的文件中(比如
string_ex.rb
)或者一个子目录中(比如extensions
或者core_ext
),这样的话,很明显什么被扩展了,并且人们很容易看到它们是如何被扩展或者改变的。猴子修补可能出现问题的地方是,当您更改核心对象的某些现有行为时,会导致其他一些预期原始功能会出现问题的代码出现问题。
rjee0c153#
object
类定义了send
,并且所有对象都继承了它。你“发送”一个对象到send
方法。send
方法的参数是你想要调用的方法的名称作为一个符号,后面跟着任何参数和一个可选块。你也可以使用__send__
。编辑..
您可能需要使用
define_method
方法:添加示例方法。要添加类方法:
型
但是,您不能定义需要块的方法。
读一读this chapter from Why's Poignant Guide可能是件好事,你可以跳到“Dwemthy的数组”来了解元编程的内容。
r1wp621o4#
谢谢你们。
更重要的是,我学会了权衡手头的情况,并决定重新打开核心(或库)类是否是一个好主意。
FWIW,一个朋友指出了我一直在寻找的
send
实现。但是现在我看了一下,它比所有其他实现更接近monkeypatching:)nbysray55#
作为将函数附加到类或对象的替代方法,您总是可以走函数路线:
u1ehiz5o6#
如果其他人想使用你的代码(比如gem),你所描述的“猴子补丁”确实会是个问题。谁能说他们不会也想添加一个名为do_magic的String方法呢?一个方法会覆盖另一个方法,这可能会很难调试。如果你的代码有可能是开源的,那么最好创建你自己的类:
现在,如果你想变魔术你可以
92vpleto7#
您可以尝试refinements:
使用它:
在这里,我们将monkeypatch严格地命名为
module Foo
作用域,正常的功能在模块之外恢复,这也适用于类,我们也可以将作用域定义为文件:型
如果benefits aren't clear,命名空间monkeypatch提供了在特定模块、类或文件中使用流畅的monkeypatch语法的能力,而在使用其他monkeypatch
String
的库(如activesupport)时没有冲突的风险。有关详细信息,请参见the docs。