SBT scala猴子补丁库

时间:2017-08-01 19:27:52

标签: java scala sbt monkeypatching

我想用一个带有更多参数的自定义类替换库中的case类。

我不想从库中排除任何内容。我正在做的是在我的项目中创建一个具有相同包名的类,但它在运行时引发了错误。

示例:

  • 图书馆:mamilo.rosa.jar:/com/mamilo/rosa/CaseClassA.scala
  • 我的项目:src/scala/com/mamilo/rosa/CaseClassA.scala

我想要做的是从库中删除该类或将其替换为我的类,但它仍然会引发运行时错误:

java.lang.NoSuchMethodError: com.mamilo.rosa.CaseClassA.<init>(Lscala/collection/Seq;...)

修改

我正在尝试向此案例类添加新参数:https://github.com/sksamuel/elastic4s/blob/master/elastic4s-core/src/main/scala/com/sksamuel/elastic4s/searches/SearchDefinition.scala

将使用哪个并转换为HTTP请求(我也会尝试覆盖)。我想要做的是在他的库中添加一些更改,当它变好时,我可以提交一些带有一些更改的PR,但是我在我的项目中将其作为依赖包含此库。

2 个答案:

答案 0 :(得分:1)

这里有两个选项:

1)添加implicit class转换,例如RichSearchDefinition,当隐式转换在范围内时,它允许您使用自己的方法。这被称为“丰富我的图书馆”(或有时候“皮条客我的图书馆”)模式。代码看起来大致如下:

object Implicits {
  implicit class RichSearchDefiniton(sd: SearchDefinition) {
    // Define methods here that you'd like to use on `SearchDefinition`
    def printSomething: Unit = println("This is an example of enriching a library.")
  }
}

只要您需要此功能,您只需导入隐式转化:import mypackage.Implicits._

2)在本地更改库,将版本号更改为0.0.1-LOCAL,并使用sbt publishLocal发布本地副本。在您的项目中,您可以依赖此本地发布的库。如果您对它的工作感到满意,可以提交一份拉动请求。这里有一点需要注意的是,如果elastic4s被传递到另一个依赖项,那么您必须在build.sbt文件中exclude

答案 1 :(得分:0)

您可以定义从类型到类型的隐式转换,反之亦然,如下所示:

// All of their existing stuff
case class TheirType(a: Int, b: String)
def theirFunction(x: TheirType) = Unit

// Your new case class
case class YourType(a: Int, b: String, c: Boolean)
def yourFunction(yourType: YourType) = Unit

// Define the implicit functions to convert from one type to another (and back)
implicit def theirsToYours(t: TheirType): YourType = YourType(t.a, t.b, true /* You will need to supply some value here */)
implicit def yoursToTheirs(y: YourType): TheirType = TheirType(y.a, y.b)

// You can now pass your type to their functions and vice-versa
val y = YourType(10, "abc", false)
theirFunction(y)

val t = TheirType(99, "123")
yourFunction(t)

这里的缺点是您需要为新参数决定一些默认值,因为它们的现有函数无法自己创建该值。