Scala猴子补丁与Ruby相比
在Scala中,您可以使用隐式进行Monkey修补,但昨天我在ruby wih Fixnum中看到了这个示例,这是一件愚蠢的事情,但我想在Scala中实现它Scala猴子补丁与Ruby相比,ruby,scala,monkeypatching,Ruby,Scala,Monkeypatching,在Scala中,您可以使用隐式进行Monkey修补,但昨天我在ruby wih Fixnum中看到了这个示例,这是一件愚蠢的事情,但我想在Scala中实现它 class Fixnum def to_roman 'I'*self #only works until 3, but only for this purpose end def +(other) self - other end end puts 2.to_roman #This prin
class Fixnum
def to_roman
'I'*self #only works until 3, but only for this purpose
end
def +(other)
self - other
end
end
puts 2.to_roman #This prints "II"
puts 1 + 1 #This prints 0
然而,在scala中,我无法使用+(逆)方法
scala最好没有Ruby那样的全局monkey补丁?scala只会尝试为找不到的方法找到隐式转换。因为Scala找到了一个
Int.+
方法,所以它不会试图寻找隐式转换,而不是toRoman
,Scala没有找到该方法,因此会用toRoman
方法搜索从Int
到某种类型的隐式转换。<
class WrappedInt(val n: Int) {
def + (other: Int): Int = {
n - other
}
}
implicit def unpack(wi: WrappedInt): Int = {
wi.n
}
// usage
val wrapped = new WrappedInt(5)
println(wrapped + 3) // performs 5 - 3
println(wrapped * 2) // 5 * 2 (`unpack` is called first)
但是请注意,如果将WrappedInt
传递给需要Int
的方法,则该方法将对未包装的值进行操作,因此“补丁”在该方法内不会处于活动状态:
def addOne(n: Int) = {
n + 1
}
println(addOne(new WrappedInt(5))) // Prints 6 (no patch)
我认为最好不要允许全局修补-这是非常危险的,因为如果你孤立地查看一个类,没有迹象表明有什么东西被修补过。项目中的每个人都需要学习和记忆所有这些无形中发生的事情。如果你正在处理多个项目,你需要记住哪个项目有哪个补丁。使用Scala时,必须显式导入第三方隐式,因此当前文件或范围中有一些迹象表明正在发生特殊情况
Ruby有一些改进,但可能是因为修补非常简单,而且在文化中根深蒂固
def addOne(n: Int) = {
n + 1
}
println(addOne(new WrappedInt(5))) // Prints 6 (no patch)