Scala猴子补丁与Ruby相比

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

在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 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)