4

My API prototype is the following:

I have third party API object named ZResponseHandler which has method

printZ(z:Z) 

no I have the following:

case class X
case class Y 
case class Z(x:X,y:Y)

now when I use my API calling printZ method with new z instance it works OK.

ZResponseHandler.printZ(new Z(x,y))

but I would like to create something like this:

implicit def convertXYtoZ(x:X,y:Y):Z = new Z(x,y)

ZResponseHandler.printZ(x,y)

this code gives me compilation error - too many arguments for method printZ:

is there any way to make any implicit class which will accept printZ(x,y)?

user2864740
  • 60,010
  • 15
  • 145
  • 220
danny.lesnik
  • 18,479
  • 29
  • 135
  • 200
  • Take a look at [the Magnet pattern](http://spray.io/blog/2012-12-13-the-magnet-pattern/). It may be more complexity than you want, but it can do this and more. – wingedsubmariner Jun 12 '14 at 02:26

2 Answers2

2

Implicits can be used wrap or "pimp" the receiver to decorate it with more methods.

class R {
  def m (s: String) = println(s)
}

// This uses an anonymous type, but it could also return
// `new RichR(r)` or similar as appropriate.
implicit def toRichR(r: R) = new {
    def m(a: String, b: String) = r.m(a + " " + b)
}

val r = new R()
r.m("hello", "world") // -> toRichR(r).m("hello", "world")

Implicit classes (Scala 2.10+) also allow the above pattern to be written more clearly.

implicit class RichR(r: R) {
    def m(a: String, b: String) = r.m(a + " " + b)
}

Objects can also be "pimped" in Scala 2.10 (but not 2.8)

object R {
  def m (s: String) = println(s)
}

// uses TheObject.type
implicit def toRichR(_r: R.type) = new {
    // (could use _r.m instead of R.m)
    def m(a: String, b: String) = R.m(a + " " + b)
}

R.m("hello", "world") // -> toRichR(r).m("hello", "world")

(There are also implicit objects, but I could not get such to work without a common [non-object] base type.)

Community
  • 1
  • 1
user2864740
  • 60,010
  • 15
  • 145
  • 220
2

An implicit method will convert a single argument, so you can't change the arity (number of parameters). However, you might be able to get around this using a Tuple:

implicit def convertXYtoZ(t: (X,Y) ):Z = new Z(t._1, t._2)
ZResponseHandler.printZ(x,y)
Mario Camou
  • 2,303
  • 16
  • 28