How to mix-in a trait to instance? - scala

Given a trait MyTrait:
trait MyTrait {
def doSomething = println("boo")
}
it can be mixed into a class with extends or with:
class MyClass extends MyTrait
It can also be mixed upon instantiating a new instance:
var o = new MyOtherClass with MyTrait
o.doSomething
But...can the trait (or any other if that makes a difference) be added to an existing instance?
I'm loading objects using JPA in Java and I'd like to add some functionality to them using traits. Is it possible at all?
I'd like to be able to mix in a trait as follows:
var o = DBHelper.loadMyEntityFromDB(primaryKey);
o = o with MyTrait //adding trait here, rather than during construction
o.doSomething

I have a idea for this usage:
//if I had a class like this
final class Test {
def f = println("foo")
}
trait MyTrait {
def doSomething = {
println("boo")
}
}
object MyTrait {
implicit def innerObj(o:MixTest) = o.obj
def ::(o:Test) = new MixTest(o)
final class MixTest private[MyTrait](val obj:Test) extends MyTrait
}
you can use this trait as below:
import MyTrait._
val a = new Test
val b = a :: MyTrait
b.doSomething
b.f
for your example code:
val o = DBHelper.loadMyEntityFromDB(primaryKey) :: MyTrait
o.doSomething
I hope this can help you.
UPDATED
object AnyTrait {
implicit def innerObj[T](o: MixTest[T]):T = o.obj
def ::[T](o: T) = new MixTest(o)
final class MixTest[T] private[AnyTrait](val obj: T) extends MyTrait
}
but this pattern has some restrict, you can't use some implicit helper method that defined already.
val a = new Test
a.f
val b = a :: AnyTrait
b.f1
b.f
val c = "say hello to %s" :: AnyTrait
println(c.intern) // you can invoke String's method
println(c.format("MyTrait")) //WRONG. you can't invoke StringLike's method, though there defined a implicit method in Predef can transform String to StringLike, but implicit restrict one level transform, you can't transform MixTest to String then to StringLike.
c.f1
val d = 1 :: AnyTrait
println(d.toLong)
d.toHexString // WRONG, the same as above
d.f1

An existing runtime object in the JVM has a certain size on the heap. Adding a trait to it would mean altering its size on the heap, and changing its signature.
So the only way to go would be to do some kind of transformation at compile time.
Mixin composition in Scala occurs at compile time. What compiler could potentially do is create a wrapper B around an existing object A with the same type that simply forwards all calls to the existing object A, and then mix in a trait T to B. This, however, is not implemented. It is questionable when this would be possible, since the object A could be an instance of a final class, which cannot be extended.
In summary, mixin composition is not possible on existing object instances.
UPDATED:
Related to the smart solution proposed by Googol Shan, and generalizing it to work with any trait, this is as far as I got. The idea is to extract the common mixin functionality in the DynamicMixinCompanion trait. The client should then create a companion object extending DynamicMixinCompanion for each trait he wants to have the dynamic mixin functionality for. This companion object requires defining the anonymous trait object gets created (::).
trait DynamicMixinCompanion[TT] {
implicit def baseObject[OT](o: Mixin[OT]): OT = o.obj
def ::[OT](o: OT): Mixin[OT] with TT
class Mixin[OT] protected[DynamicMixinCompanion](val obj: OT)
}
trait OtherTrait {
def traitOperation = println("any trait")
}
object OtherTrait extends DynamicMixinCompanion[OtherTrait] {
def ::[T](o: T) = new Mixin(o) with OtherTrait
}
object Main {
def main(args: Array[String]) {
val a = "some string"
val m = a :: OtherTrait
m.traitOperation
println(m.length)
}
}

I usually used a implicit to mix in a new method to an existing object.
See, if I have some code as below:
final class Test {
def f = "Just a Test"
...some other method
}
trait MyTrait {
def doSomething = {
println("boo")
}
}
object HelperObject {
implicit def innerObj(o:MixTest) = o.obj
def mixWith(o:Test) = new MixTest(o)
final class MixTest private[HelperObject](obj:Test) extends MyTrait
}
and then you can use MyTrait method with an already existing object Test.
val a = new Test
import HelperObject._
val b = HelperObject.mixWith(a)
println(b.f)
b.doSomething
in your example, you can use like this:
import HelperObject._
val o = mixWith(DBHelper.loadMyEntityFromDB(primaryKey));
o.doSomething
I am thinking out a prefect syntax to define this HelperObject:
trait MyTrait {
..some method
}
object MyTrait {
implicit def innerObj(o:MixTest) = o.obj
def ::(o:Test) = new MixTest(o)
final class MixTest private[MyTrait](obj:Test) extends MyTrait
}
//then you can use it
val a = new Test
val b = a :: MyTrait
b.doSomething
b.f
// for your example
val o = DBHelper.loadMyEntityFromDB(primaryKey) :: MyTrait
o.doSomething

What about an implicit class? It seems easier to me compared to the way in the other answers with a final inner class and a "mixin"-function.
trait MyTrait {
def traitFunction = println("trait function executed")
}
class MyClass {
/**
* This inner class must be in scope wherever an instance of MyClass
* should be used as an instance of MyTrait. Depending on where you place
* and use the implicit class you must import it into scope with
* "import mypackacke.MyImplictClassLocation" or
* "import mypackage.MyImplicitClassLocation._" or no import at all if
* the implicit class is already in scope.
*
* Depending on the visibility and location of use this implicit class an
* be placed inside the trait to mixin, inside the instances class,
* inside the instances class' companion object or somewhere where you
* use or call the class' instance with as the trait. Probably the
* implicit class can even reside inside a package object. It also can be
* declared private to reduce visibility. It all depends on the structure
* of your API.
*/
implicit class MyImplicitClass(instance: MyClass) extends MyTrait
/**
* Usage
*/
new MyClass().traitFunction
}

Why not use Scala's extend my library pattern?
https://alvinalexander.com/scala/scala-2.10-implicit-class-example
I'm not sure what the return value is of:
var o = DBHelper.loadMyEntityFromDB(primaryKey);
but let us say, it is DBEntity for our example. You can take the class DBEntity and convert it to a class that extends your trait, MyTrait.
Something like:
trait MyTrait {
def doSomething = {
println("boo")
}
}
class MyClass() extends MyTrait
// Have an implicit conversion to MyClass
implicit def dbEntityToMyClass(in: DBEntity): MyClass =
new MyClass()
I believe you could also simplify this by just using an implicit class.
implicit class ConvertDBEntity(in: DBEntity) extends MyTrait
I particularly dislike the accepted answer here, b/c it overloads the :: operator to mix-in a trait.
In Scala, the :: operator is used for sequences, i.e.:
val x = 1 :: 2 :: 3 :: Nil
Using it as a means of inheritance feels, IMHO, a little awkward.

Related

Mixin to wrap every method of a Scala trait

Suppose I have a trait Foo with several methods. I want to create a new trait which extends Foo but "wraps" each method call, for example with some print statement (in reality this will be something more complicated / I have a couple of distinct use cases in mind).
trait Foo {
def bar(x: Int) = 2 * x
def baz(y: Int) = 3 * y
}
I can do this manually, by overriding each method. But this seems unnecessarily verbose (and all too easy to call the wrong super method):
object FooWrapped extends FooWrapped
trait FooWrapped extends Foo {
override def bar(x: Int) ={
println("call")
super.bar(x)
}
override def baz(y: Int) ={
println("call")
super.baz(y)
}
}
scala> FooWrapped.bar(3)
call
res3: Int = 6
I was hoping to write a mixin trait, that I would be able to reuse with other traits, and use as:
trait FooWrapped extends Foo with PrintCall
That way I don't have to manually override each method (the mixin would do this for me).
Is it possible to write such a mixin trait in Scala? What would it look like?
Update Here is the macro. It was much less painful than I thought it will be because of quasiquotes. They are awesome. This code does only a little and you probably will have to improve it. It may not account some special situations. Also it assumes that neither parent class nor it's method has type params, it wraps only the methods of the given class or trait, but not it's parents methods, it may not work if you have auxilary constructors etc. Still I hope it will give you an idea of how to do that for your specific needs, making it working for all of the situations unfortunately is too big job for me right now.
object MacrosLogging {
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
def log_wrap[T](): T = macro log_impl[T]
def log_impl[T : c.WeakTypeTag](c: blackbox.Context)(): c.Expr[T] = {
import c.universe._
val baseType = implicitly[c.WeakTypeTag[T]].tpe
val body = for {
member <- baseType.declarations if member.isMethod && member.name.decodedName.toString != "$init$"
method = member.asMethod
params = for {sym <- method.paramLists.flatten} yield q"""${sym.asTerm.name}: ${sym.typeSignature}"""
paramsCall = for {sym <- method.paramLists.flatten} yield sym.name
methodName = member.asTerm.name.toString
} yield {
q"""override def ${method.name}(..$params): ${method.returnType} = { println("Method " + $methodName + " was called"); super.${method.name}(..$paramsCall); }"""
}
c.Expr[T] {q""" { class A extends $baseType { ..$body }; new A } """}
}
}
If you do not want to create an instance, but you do want to add logging only for your trait so you could mixin further, you can do this with relatively the same code, but using macro paradise type annotations: http://docs.scala-lang.org/overviews/macros/annotations These allow you to tag your class definitions and perform modifications right inside the definitions
You could do something like you want with Dynamic, but there is a catch - you can't make it of original type, so it's not a mixin. Dynamic starts to work only if type checks fails, so you can't mixin real type (or I do not know how to do that). The real answer would probably require macros (as #AlexeyRomanov suggested in comments), but I am not sure how to write one, maybe I'll come up with it later. Still Dynamic might work for you if you are not looking for DI here
trait Foo {
def bar(x: Int) = 2 * x
def baz(y: Int) = 3 * y
}
import scala.reflect.runtime.{universe => ru}
import scala.language.dynamics
trait Wrapper[T] extends Dynamic {
val inner: T
def applyDynamic(name: String)(args: Any*)(implicit tt: ru.TypeTag[T], ct: ClassTag[T]) = {
val im = tt.mirror.reflect(inner)
val method = tt.tpe.decl(ru.TermName(name)).asMethod
println(method)
val mm = im.reflectMethod(method)
println(s"$name was called with $args")
mm.apply(args:_*)
}
}
class W extends Wrapper[Foo] {
override val inner: Foo = new Foo() {}
}
val w = new W // Cannot be casted to Foo
println(w.bar(5)) // Logs a call and then returns 10
You can read more about Dynamic here: https://github.com/scala/scala/blob/2.12.x/src/library/scala/Dynamic.scala

Is it better to use vals or object when providing instances of a typeclass in Scala

The type class pattern in Scala involves defining a trait such as:
trait Show[T] {
def show(obj: T): String
}
Then you can define instantiations of this type class as such:
object Show {
implicit val string = new Show[String] {
def show(obj: String): String = obj
}
implicit object BooleanShow extends Show[Boolean] {
def show(obj: Boolean): String = obj.toString
}
}
The advantage of defining these instantiations for basic types in the companion object is that they are automatically in scope whenever the type class is concerned (roughly).
Functionally it would appear defining the instantiation as an implicit val or an implicit object does not change much.
Is there a difference? Is one way better than the other?
There is actually more than the type names between val and object.
You know, object in Scala is something like a singleton in Java.
Maybe you thought that both string and BooleanShow are in an object not a class so they have no difference, but that's not true.
They are val and object no matter what.
Try this in Scala REPL.
trait Show[T] {
def show(obj: T): String
}
object Show {
println("!! Show created")
implicit val string = new Show[String] {
println("!! string created")
def show(obj: String): String = obj
}
implicit object BooleanShow extends Show[Boolean] {
println("!!BooleanShow created")
def show(obj: Boolean): String = obj.toString
}
}
If only the definition is done, then no printlns are executed afterwards, since Show is a singleton in effect. It's not created yet.
Next, execute Show in Scala REPL.
scala> Show
!! Show created
!! string created
res0: Show.type = Show$#35afff3b
You see, printlns in Show and Show.string were called, but the one in Show.BooleanShow was not.
You can execute Show.BooleanShow next in Scala REPL.
scala> Show.BooleanShow
!!BooleanShow created
res1: Show.BooleanShow.type = Show$BooleanShow$#18e419c5
Show.BooleanShow was initialized at last. It is a singleton, so it is lazy.
Basically, your question is the same as val and object inside a scala class? except that your val and object are defined in an object, but the linked question tries to find differences val and object defined in a class and the method in val uses reflection (but yours uses overriding, so no reflection is involved). implicit basically does not make difference in what they are.
I think you already know the difference between class and object. Further information can be found in the linked question.
Since they say always to use explicit types for implicits, prefer val over object.
Compare Why can't Scala find my typeclass instance defined implicitly in the companion object, when the typeclass is not in a dedicated source file? where it makes a difference.
Make it lazy if necessary.
Elaboration:
scala> trait T
defined trait T
scala> object X { implicitly[T] ; object O extends T }
<console>:8: error: could not find implicit value for parameter e: T
object X { implicitly[T] ; object O extends T }
^
scala> object X { implicitly[T] ; implicit object O extends T }
<console>:8: error: could not find implicit value for parameter e: T
object X { implicitly[T] ; implicit object O extends T }
^
scala> object X { implicitly[O.type] ; implicit object O extends T }
defined object X
scala> object X { implicitly[T] ; implicit object O extends T ; implicit def y = O }
<console>:8: error: could not find implicit value for parameter e: T
object X { implicitly[T] ; implicit object O extends T ; implicit def y = O }
^
scala> object X { implicitly[T] ; implicit object O extends T ; implicit def y: T = O }
defined object X
The inferred type of O is the singleton type O.type.
With val x = new X { } you are creating an anonymous subclass of X, whereas with object x extends X you create a "proper" subclass. I would think that the overhead of an object is minimal, and as #applicius points out, it has proper name. Therefore I suggest to go for the object in this case.

Creating an object dynamically by its name (string)

I have a trait and an object inherited from this trait:
trait MyTrait {
def method1(a: Int)
}
object MyObject extends MyTrait {
def method1(a: Int) = //....
}
Assuming I have only the full name of an object as a string (namespace + its name) and knowing it's inherited from MyTrait, how do I
create it at runtime
call its method method1
return it to a calling code so that other clients can use it?
I read about reflection in Scala, but, oddly enough, almost all I found was about creating a class at runtime.
UPDATE:
I wonder, why doesn't this work:
scala> object MyObject { def method1(a: Int) = 123456 }
defined module MyObject
scala> val cs = Class.forName("MyObject")
java.lang.ClassNotFoundException: MyObject
due to the error java.lang.ClassNotFoundException: MyObject
If you want to get an instance of a singleton scala object via reflection, you can try this:
package code
object ReflectTest extends App{
val clazz = Class.forName("code.MyObject$")
val myObj = clazz.getField("MODULE$").get(classOf[MyTrait]).asInstanceOf[MyTrait]
println(myObj.method1(2))
}
trait MyTrait {
def method1(a: Int):Int
}
object MyObject extends MyTrait {
def method1(a: Int) = a + 1
}
Now I'm not a big fan of obtaining instances of scala objects via reflection (seems kinds silly given that it's a singleton) but maybe you have a valid use case for this.

How to define generic type in Scala?

In Slick 2, we can map tables like this:
case class Cooler(id: Option[Int], minTemp: Option[Double], maxTemp: Option[Double])
/**
* Define table "cooler".
*/
class Coolers(tag: Tag) extends Table[Cooler](tag, "cooler") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def minTemp = column[Double]("min_temp", O.Nullable)
def maxTemp = column[Double]("max_temp", O.Nullable)
def * = (id.?, minTemp.?, maxTemp.?) <> (Cooler.tupled, Cooler.unapply _)
}
object Coolers {
val tableQuery = TableQuery[Coolers]
}
because I have a lot of tables, I want to define generic methods for them, like find, delete, update so I have to define these methods in a super class from where to extend my objects (object Coolers extends TableUtils[Coolers, Cooler]). In order to define those methods, I need tableQuery to move out of my object in this super class, so I tried it like:
abstract class TableUtils[T <: Table[A] , A] {
val tableQuery = TableQuery[T]
}
but I receive an error on tableQuery definition:
class type required but T found
Does anybody know what I am doing wrong?
When you do TableQuery[T] you are in fact calling TableQuery.apply, which is actually a macro.
The body of this macro tries to instantiate T, but in your case T has become an (unknown) type parameter that the compiler does not know how to instantiate. The problem is similar to trying to compile this:
def instantiate[T]: T = new T
// Does not compile ("class type required but T found")
The net effect is that TableQuery.apply can only be used on concrete types.
You could work around that using a type class to capture the call to TableQuery.apply (at the point where the concrete type is known) along with an implicit macro to provide an instance of this type class. Then you would have something like:
abstract class TableUtils[T <: Table[A] : TableQueryBuilder, A] {
val tableQuery = BuildTableQuery[T]
}
Where TableQueryBuilder is the type class and BuildTableQuery is an alternate version of TableQuery.apply that will forward to the TableQueryBuilder instance to perform the actual instantiation.
I've added an implementation as part of another answer here.
It will be much easier (if less convenient) to just declare tableQuery as an abstract value and define it in every concrete derived class of TableUtils:
abstract class TableUtils[T <: Table[A] , A] {
val tableQuery: TableQuery[T, T#TableElementType]
// define here your helper methods operating on `tableQuery`
}
object Coolers extends TableUtils[Coolers, Cooler] {
val tableQuery = TableQuery[Coolers]
}
Here is one solution:
At first, define this to avoid class type issue..
class Service[T <: Table[_]](path: String, cons: Tag => T){
lazy val db = Database.forConfig(path)
def query = TableQuery[T](cons)
}
Then use it this way, Post is sub class of Table:
object Abcd {
object Def extends Service[Post]("mydb", abc) {
def test = {
//db
val q = query.drop(1).take(20)
val r = db.run(q.result)
println(q.result.statements.head)
println(r)
r
}
}
private def abc(tag: Tag) = new Post(tag)
}
This solution tested ok in slick 3.x, and Play slick 1.x, since the slick 2.0 Query.scala comply to slick 3.0 Query.scala, this might work at 2 too.

Scala: How can I implement a clone method on a superclass, and use it in a subclass?

I might be approaching this the wrong way, but I'd like to have an object like this:
class MyDataStructure {
def myClone = {
val clone = new MyDataStructure
// do stuff to make clone the same as this
...
clone
}
}
class MyDataStructureExtended(val foo: String) extends MyDataStructure
Then:
val data = MyDataStructureExtended
val dataClone = data.clone
println(dataClone.foo)
So, the problem is that dataClone is of type MyDataStructure, not MyDataStructureExtended as I'd hoped.
I thought about adding a type T to the super class, that the subclass can specify (e.g. itself), but that didn't seem very promising.
As you have suggested, abstract types, or generic parameters, are what you need. Do you require that MyDataStructure not be a trait or abstract class? The following defines MyDataStructure to be an abstract class, but you can make it a trait as well.
abstract class MyDataStructure {
type T
def myClone: T
}
class MyDataStructureExtended(foo: String) extends MyDataStructure {
type T = MyDataStructureExtended
def myClone = new MyDataStructureExtended(foo)
}
The results from the Scala interpreter show that the myClone method defined in MyDataStructureExtended is the correct type.
scala> val mde = new MyDataStructureExtended("foo")
val mde = new MyDataStructureExtended("foo")
mde: MyDataStructureExtended = MyDataStructureExtended#3ff5d699
scala> val cloned = mde.myClone
val cloned = mde.myClone
cloned: MyDataStructureExtended = MyDataStructureExtended#2e1ed620
You might want to restrict T so that its type can only be that of MyDataStructure subclasses
abstract class MyDataStructure {
type T <: MyDataStructure
def myClone: T
}
I don't know your requirements, but I believe that Scala 2.8 will have some nice functionality with case classes and named arguments that allow one to clone case classes with a copy method.
Assuming you want to minimize amount of ceremony in the subclasses, here is my suggestion:
class A extends Cloneable {
protected[this] def myCloneImpl[T] = {
val justLikeMe = this.clone
// copy values and such.
// Note that the Object.clone method already made a shallow copy, but you may want
// to deepen the copy or do other operations.
justLikeMe.asInstanceOf[T]
}
def myClone = myCloneImpl[A]
}
class B extends A {
override def myClone = myCloneImpl[B]
}
By extending java.lang.Cloneable and calling the Object.clone method, you ensure that your runtime type is the same as the object being cloned. The static type is coerced with a type-cast (asInstanceOf[T]). You will need to override the myClone method in each subclass and specify the type, but it should be a one-liner.
Hard to say whether you're doing it right with such a vague problem description, but it's actually pretty straightforward to do this. You can simply override myclone in MyDataStructureExtended such that it returns the more specific type. When you have a variable of the more specific type, you'll be able to use the more specific clone method as well.
Example code in case that description was unclear:
class A {
def getMe = this
}
class B extends A {
override def getMe = this
def isAnInstanceOfB = true
}
And a corresponding REPL session:
scala> val a = new A
a: A = A#1a6eeab
scala> val b = new B
b: B = B#a36771
scala> a.getMe
res0: A = A#1a6eeab
scala> a.getMe.isAnInstanceOfB
<console>:7: error: value isAnInstanceOfB is not a member of A
a.getMe.isAnInstanceOfB
^
scala> b.isAnInstanceOfB
res2: Boolean = true
scala> b.getMe.isAnInstanceOfB
res3: Boolean = true
I think this could be the solution. This is not inherited and you can do some modification to achieve your thing. Good Luck.
class CloneableClass extends scala.Cloneable {
def myMethod: Unit = println("Inside "+this.getClass)
override def clone(): CloneableClass =super.clone().asInstanceOf[this.type]
}
class CloneableDemo {
val cc = new CloneableClass
val cc1 = cc.clone()
cc1.myMethod
}
object CloneObject extends App {
val cd = new CloneableDemo
}