如果Ruby和Python都允许猴子修补,为什么在Ruby中更具争议性呢?

Pau*_*ter 15 ruby python language-features monkeypatching

在许多讨论中,我听说过人们对语言有所保留的Ruby,猴子修补问题成为他们主要关注的问题之一.

但是,我很少听到在Python上下文中提出的相同论点,尽管在Python语言中也允许这样做.

为什么这个区别?

Python是否包含不同类型的安全措施以最大限度地降低此功能的风险?

Mik*_*use 21

这是一种在Python中不太常用的技术,部分原因是因为Python中的"核心"类(用C实现的那些)并不是真正可修改的.另一方面,在Ruby中,由于它在内部实现的方式(不是更好,只是不同),几乎任何东西都可以动态修改.

从哲学上讲,它在Python社区中往往是不受欢迎的,在Ruby世界中则显然不那么令人讨厌.我不知道为什么你断言它更具争议性(你可以链接到权威参考吗?) - 我的经验是,如果用户应该知道可能的后果,那么猴子修补是一种公认​​的技术.


Kei*_*han 16

语言可能允许它,但两个社区都不容忍这种做法.Monkeypatching在任何一种语言中都不会被宽容,但是你在Ruby中经常会听到它,因为它使用的开放类的形式使得它很容易monkeypatch一个类,因此,它在Ruby社区中更容易被接受,但是仍然不满意.Monkeypatching在Python中不那么流行或不那么容易,这就是为什么你不会在那个社区听到与它相反的论点.Python没有做任何Ruby不做的事情来阻止这种做法.

您在Ruby中经常听到/阅读它的原因是这在Ruby中:

class MyClass
  def foo
    puts "foo"
  end
end
Run Code Online (Sandbox Code Playgroud)
class MyClass
  def bar
    puts "bar"
  end
end
Run Code Online (Sandbox Code Playgroud)

会给你一个包含两个方法,一类foobar,而这在Python:

class MyClass:
    def foo(self):
        print "foo"
Run Code Online (Sandbox Code Playgroud)
class MyClass:
    def bar(self):
        print "bar"
Run Code Online (Sandbox Code Playgroud)

将为您提供仅包含该方法bar的类,因为类的重新定义完全破坏了先前的定义.要在Python中使用monkeypatch,你实际上必须写这个:

class MyClass:
    def foo(self):
        print "foo"
Run Code Online (Sandbox Code Playgroud)
def bar(self):
    print "bar"
MyClass.bar = bar
Run Code Online (Sandbox Code Playgroud)

这比Ruby版本更难.仅这一点使Ruby代码比Python代码更容易monkeypatch.

  • 您可以轻松地在Python中获得相同的效果.删除第二个"class MyClass"行,并在定义bar后将"MyClass.bar = bar"放在最后.此外,您忘记了类函数的self参数. (4认同)

Mat*_*kel 16

作为一个熟悉Ruby(并且喜欢它)的Python程序员,我认为与Python开始变得流行时有一些相似之处.

C和Java程序员会"抨击"Python,声称它不是真正的语言,并且其类型的动态性质将是危险的,并允许人们创建"坏"代码.随着Python变得越来越流行,其快速开发时间的优势变得明显,更不用说冗长的语法了:

// Java
Person p = new Person();
Run Code Online (Sandbox Code Playgroud)
# Python
p = Person()
Run Code Online (Sandbox Code Playgroud)

我们开始看到Java的更高版本中出现了一些更动态的功能.Autoboxing和-unboxing使处理原语变得不那么麻烦,而Generics允许我们编写一次代码并将其应用于多种类型.

我看到了Ruby的一个关键灵活特性 - 猴子补丁,被Python人群吹捧为危险之中.在今年开始向学生教授Ruby之后,我认为能够"修复"现有类的实现,即使是属于系统的类,也非常强大.

当然,你可能搞砸了,你的程序可能会崩溃.我也可以很容易地在C中进行段错误.Java应用程序可能会死于火焰死亡.

事实是,我认为Monkey Patching是动态和元编程的下一步.有趣,因为它自Smalltalk以来一直存在.

  • 我听说过"鸭子打孔"一词与"猴子修补"一样.这是一个关于"鸭子打字"的游戏(如果它像鸭子一样嘎嘎叫,那么它也可能是一只鸭子,即使它是一个整数).如果它不像鸭子那样嘎嘎叫,那么你就一直打它直到它(添加新的方法等). (3认同)

S.L*_*ott 13

"Python是否包含不同类型的安全措施以最大限度地降低此功能的风险?"

是.社区拒绝这样做.保障措施完全是社会性的.