This is probably covered by the blog entry by Jesse Eichar—still I can't figure out how to correct the following without resorting to lazy vals so that the NPE is fixed:
Given
trait FooLike { def foo: String }
case class Foo(foo: String) extends FooLike
trait Sys {
type D <: FooLike
def bar: D
}
trait Confluent extends Sys {
type D = Foo
}
trait Mixin extends Sys {
val global = bar.foo
}
First attempt:
class System1 extends Mixin with Confluent {
val bar = Foo("npe")
}
new System1 // boom!!
Second attempt, changing mixin order
class System2 extends Confluent with Mixin {
val bar = Foo("npe")
}
new System2 // boom!!
Now I use both bar and global very heavily, and therefore I don't want to pay a lazy-val tax just because Scala (2.9.2) doesn't get the initialisation right. What to do?
You can use an early initializer:
class System1 extends {
val bar = Foo("npe")
} with Mixin with Confluent {
// ...
}
scala> new System1
res3: System1 = System1#1d0bfedd
Related
I'm tying to create a typesafe wrapper around lwjgl. Most importantly, I want it to be a compile time error to pass the wrong constants to a function, e.g. calling glEnable(GL_ARRAY_BUFFER). This whould be rather easy if it weren't for different contexts supporting different constants for the same function.
I figured I'd use type classes to model which constants can be passed to which function. I've got a solution but admittedly it's a bit ugly and fails to apply a certain implicit:
trait GlConst { val glConst: Int }
trait GlConstCompanion[C <: GlConst] { val instance: C }
class GlDepthTest private () extends GlConst { val glConst = GL_DEPTH_TEST }
object GlDepthTest extends GlConstCompanion[GlDepthTest] {
val instance = new GlDepthTest
}
class GlLineSmooth private () extends GlConst { val glConst = GL_LINE_SMOOTH }
object GlLineSmooth extends GlConstCompanion[GlLineSmooth] {
val instance = new GlLineSmooth
}
class GlArrayBuffer private () extends GlConst { val glConst = GL_ARRAY_BUFFER }
object GlArrayBuffer extends GlConstCompanion[GlArrayBuffer] {
val instance = new GlArrayBuffer
}
// type class for arguments to glEnable
trait GlEnableCap[T <: GlConst] extends GlConst
object GlContext33 {
implicit object GlDepthTestIsEnableCap extends GlEnableCap[GlDepthTest] {
val glConst = GlDepthTest.instance.glConst
}
implicit object GlLineSmoothIsEnableCap extends GlEnableCap[GlLineSmooth] {
val glConst = GlLineSmooth.instance.glConst
}
def glEnable[T <: GlConst : GlEnableCap](t: T): Unit = println(implicitly[GlEnableCap[T]].glConst)
}
object Test extends App {
import GlContext33._
implicit def constComp2Const[C <: GlConst](cc: GlConstCompanion[C]): C = cc.instance
// works
glEnable(GlDepthTest.instance)
// fails to apply implicit glConstComp2Comp
glEnable(GlDepthTest)
// fails intentionally
glEnable(GlArrayBuffer)
}
Is there a way to get the implicit to work? Or is there an even better way to wrap OpenGL's constants?
As a rule of thumb, don't use implicits if you don't have to.
In this case you can solve it just as well using only type bounds:
// Start writing your ScalaFiddle code here
val GL_DEPTH_TEST = 1
val GL_LINE_SMOOTH = 1
val GL_ARRAY_BUFFER = 1
trait GlConstCap
trait GlEnableConstCap extends GlConstCap
trait GlBufferConstCap extends GlConstCap
trait GlConst[C <: GlConstCap] { val value: Int }
object GlDepthTest extends GlConst[GlEnableConstCap] {
val value = GL_DEPTH_TEST
}
object GlLineSmooth extends GlConst[GlEnableConstCap] {
val value = GL_LINE_SMOOTH
}
object GlArrayBuffer extends GlConst[GlBufferConstCap] {
val value = GL_ARRAY_BUFFER
}
object GlContext33 {
def glEnable[T <: GlConst[GlEnableConstCap]](t: T): Unit = println(t.value)
}
object Test extends App {
import GlContext33._
// works
glEnable(GlDepthTest)
// fails to apply implicit glConstComp2Comp
glEnable(GlDepthTest)
// fails intentionally
glEnable(GlArrayBuffer)
}
Try it out!
Note: You might want to add contravariance to C in GlConst if you want to create deeper inheritance structures of GlConstCap.
I hope this helps.
Assume the following situation
I have a trait A and a trait B that both declare a value that has the same name and type.
A defines the value explicitly, while B defines it implicitly
A and B are from external libraries and can not be changed. I don't want to fork.
I want to use both of them in a class C that is in my own code
How can I get them to align inside class C?
I want B.foo to be the value from A.foo
// External code, cant touch
trait A{
val foo = "boom"
}
trait B{
implicit val foo: String
}
// My class
class C extends A with B {
//uh oh??
}
Update (with help from Jasper-M)
// External code, cant touch
trait A{
val foo = "boom"
}
trait B{
implicit val foo: String
def implBang()(implicit s: String) = s
def doTheBang() = implBang()
}
// My class
class C extends B with A {}
new C().doTheBang; // Prints "boom"
Now only question remaining, how would I get foo to be in the implicit scope for class C?
Ideally you can select the implementation you want with super[Name]. But for vals that doesn't work for some reason.
class C extends A with B {
override implicit val foo = super[A].foo
// error: super may not be used on value foo
}
So if you really need some implicit String in C I would suggest just letting linearization do its thing and define another implicit val.
class C extends A with B {
implicit val bar = foo
}
You can just override the implicit variable, like:
// My class
class C extends A with B {
override implicit val foo = "My Value"
}
I've made an enum macro, which ended up having a strange behavior.
This is the main implementation:
object Enum {
def values[A]: Seq[A] = macro Impl.values[A]
class Impl(val c: Context) {
import c.universe._
def values[A: c.WeakTypeTag]: c.Expr[A] = {
val elemType = weakTypeOf[A]
val elemSymbol = elemType.typeSymbol.asSealedClass
val elemSymbols = elemSymbol.knownDirectSubclasses.toList
val elemIdents = elemSymbols.map(s => Ident(s.asCaseClass.asModuleClass.module))
val elemSeqSymbol = weakTypeOf[Seq[A]].typeSymbol
c.Expr(Apply(Ident(elemSeqSymbol.companion), elemIdents))
}
implicit class SymbolOp(s: Symbol) {
def asSealedClass = s.asClass.ensuring(_.isSealed, s"$s is not sealed")
def asCaseClass = s.asClass.ensuring(_.isCaseClass, s"$s is not a case class")
def asModuleClass = s.asClass.ensuring(_.isModuleClass, s"$s is not an object")
}
}
}
And this is the test:
object EnumTest extends App {
sealed trait Foo
case object Moo extends Foo
case object Noo extends Foo
val values = Enum.values[Foo]
println(values)
println(Enum.values[Foo])
println({
val v = Enum.values[Foo]
v
})
}
The console should print out three same outputs, but:
List()
List(Moo, Noo)
List(Moo, Noo)
Wny does this happen? How do you deal with this?
I would appreciate if you can test it in your SBT: https://github.com/ryo0ka/enum
Thank you!
This is indeed a strange behavior, but it is hard for Scalac to do a good job here: The problem is that you use nested objects. Consider the following:
object EnumTest extends App {
sealed trait Foo
case object Moo extends Foo
case object Noo extends Foo
println(Enum.values[Foo])
case object Bar extends Foo
}
This prints List(Moo, Noo). If we move Bar before the println statement, it prints List(Moo, Noo, Bar) as we would expect.
If we move the sealed hierarchy out of the object, everything works fine.
Therefore, it seems it is probably not a smart idea to have the macro reify at the location where you define your case classes. You could make values itself a macro (whose implementation simply calls Impl.values with the right WeakTypeTag). That would probably work.
I'd like to reduce the boilerplate needed to bind these akka actors.
At current, my code looks like this:
bind(classOf[ActorRef]).
annotatedWith(Names.named("mines")).
toProvider(new TypeLiteral[ActorProvider[MyActor]]() {}).
asEagerSingleton()
I'd like it too look like:
bindActor[MyActor].withName("mines")
I've tried to subclass AbstractModule to squeeze this concept in to no avail.
Pertinent code:
class ActorProvider[T <: Actor] #Inject() ( val key:Key[T], val injector:Injector, val system: ActorSystem ) extends Provider[ActorRef] {
def get = {
system.actorOf(Props(injector.getInstance(key)))
}
}
Check out https://github.com/codingwell/scala-guice/. Here is a sample based on it. It allows for
bindActor[MyActor].withName("mines")
Keep in mind you are binding a non-generic ActorRef and not Actor itself. This will create a binding for #Named("foo") ActorRef. You should never work with Actor directly.
You cannot get Key in the provider. Provider doesn't take any contextual injections like you tried with the Key or e.g. Injection Point. What you can do is create a different instance of the provider for each actor binding and inject it with ActorSystem afterwards. Alternatively you could change the API to include the actor system instance aswell.
trait AkkaModule extends AbstractModule {
// should be:
// this: AbstractModule =>
// see http://lampsvn.epfl.ch/trac/scala/ticket/3564
import ScalaModule._
private def binderAccess = super.binder // shouldn't need super
def bindActor[T <: Actor](implicit m: Manifest[T]) = new ActorBindingBuilder {
//Hack, no easy way to exclude the bind method that gets added to classes inheriting ScalaModule
//So we experamentally figured out how many calls up is the source, so we use that
//Commit 52c2e92f8f6131e4a9ea473f58be3e32cd172ce6 has better class exclusion
val mybinder = binderAccess.withSource((new Throwable).getStackTrace()(3))
val self = (mybinder bind classOf[ActorRef]).asInstanceOf[AnnotatedBindingBuilder[ActorRef]]
}
}
object AkkaModule {
class ActorProvider(val name: String) extends Provider[ActorRef] {
#Inject var system: ActorSystem = _
def get = {
system.actorFor(system.name + "/user/" + name)
}
}
trait ActorBindingBuilder {
val mybinder: Binder
val self: AnnotatedBindingBuilder[ActorRef]
def withName(name: String) = {
val provider = new ActorProvider(name)
self.annotatedWith(Names.named(name)).toProvider(provider)
mybinder.requestInjection(provider)
}
}
}
Something like this that leverages scala's type Manifest might work
http://www.scala-lang.org/api/current/scala/reflect/Manifest.html
where Foo is analogous to ActorRef and Bla is analogous to MyActor:
scala> import com.google.inject
import com.google.inject
scala> val binder:inject.Binder = null
binder: com.google.inject.Binder = null
scala> class Foo {}
defined class Foo
scala> class Bla extends Foo {}
defined class Bla
scala> def bind[T <: Foo:Manifest] = binder.bind( classOf[Foo] ).toProvider( new
inject.TypeLiteral[inject.Provider[T]](){} ).asEagerSingleton
bind: [T <: Foo](implicit evidence$1: Manifest[T])Unit
Maybe combine that with implicit conversion to convert a Binder to a MyBinder:
http://daily-scala.blogspot.com/2009/08/implicit-methods.html
class MyBinder {
def bindActor[T <: ActorRef:Manifest]( nameToBind:String ):Unit = ...
}
object MyBinder {
implicit def binderToMyBinder( ...
}
Good luck!
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.