Ruby 中的猴子补丁
在 Ruby 中,Monkey Patch (MP) 被称为对类的动态修改,对类的动态修改意味着在运行时添加新方法或覆盖现有方法。 ruby 提供了这种能力,为编码人员提供了更大的灵活性。
Ruby 是一种非常强大且敏捷的语言,它为开发人员修补类提供了这种强大的能力。实际上,它的重要性在于修补有缺陷的类并使其方法以某种方式运行以解决问题。正如所说的能力越大责任越大,开发人员有很大的责任使用此功能来修补类而不是阻止其原始功能,因为修补会导致覆盖原始方法。
这是一个非常重要的功能,在使用时需要格外小心。下面列出了 ruby 中猴子补丁的一些基本属性。
- 如果多个库具有相同的方法,则第一个将被覆盖。
- 如果在打补丁之前没有导入该类,则会导致重新定义该类而不是对其进行修补。
- 所有补丁本质上都是全局的,实际上可以破坏多个库。
- Monkey patching 用于修补编码器拥有的类,不建议修补已经在 Ruby 中定义的经常使用的类,如哈希、列表等。
应用补丁的一般语法是简单地在类中创建一个方法,其类名与必须应用补丁的类名相同。
句法
class [class_name]
def [method_to_patch]:
#do_something
end
end
例子:
在这个例子中,Monkey patching 用于阻止用户反转字符串。
Ruby
# Ruby program to illustrate monkey patching
# Before applying patching
puts "Before blocking reverse: " +
"Geeks for Geeks".reverse
# Apply patching
class String
def reverse
"Reversing blocked!!"
end
end
# After applying patching
puts "After blocking reverse: " +
"Geeks for Geeks".reverse
Ruby
# Ruby program to illustrate monkey patching
# Before applying patching
hash = { "Geeks"=>"G",
"for"=>"F",
"geeks"=>"g" }
puts "Before blocking reverse: "
hash.delete "for"
puts "Deleted 'for' key"
puts hash
# Apply patching
class Hash
def delete(key)
"Delete blocked!!"
end
end
# After applying patching
hash = { "Geeks"=>"G",
"for"=>"F",
"geeks"=>"g" }
puts "Before blocking reverse: "
puts "Deleting 'for' key but " +
hash.delete("for")
puts hash
输出:
Before blocking reverse: skeeG rof skeeG
After blocking reverse: Reversing blocked!!
在上面的代码中,改变了 ruby 的 String 类,以阻止反转字符串的功能。在定义了补丁的方法之后,补丁实际上阻塞了类的一个基本功能,因此需要谨慎使用。
例子:
在本示例中,Monkey patching 用于阻止用户从 Hash 中删除任何键。
红宝石
# Ruby program to illustrate monkey patching
# Before applying patching
hash = { "Geeks"=>"G",
"for"=>"F",
"geeks"=>"g" }
puts "Before blocking reverse: "
hash.delete "for"
puts "Deleted 'for' key"
puts hash
# Apply patching
class Hash
def delete(key)
"Delete blocked!!"
end
end
# After applying patching
hash = { "Geeks"=>"G",
"for"=>"F",
"geeks"=>"g" }
puts "Before blocking reverse: "
puts "Deleting 'for' key but " +
hash.delete("for")
puts hash
输出:
Before blocking reverse:
Deleted 'for' key
{"Geeks"=>"G", "geeks"=>"g"}
Before blocking reverse:
Deleting 'for' key but Delete blocked!!
{"Geeks"=>"G", "for"=>"F", "geeks"=>"g"}
与上面的代码类似,这里的删除功能由于补丁而被阻止。
关于何时实际使用猴子补丁的一些基本提示:
- 需要重新打开类的情况,例如在代码重构和简化的情况下,当方法在类中以脏方式编写时。
- 当开发人员自己的类方法需要打补丁时。但是,在这种情况下不建议使用猴子补丁。