I want to create companion objects for some imported Java types, so that I do not have to use new to allocate them. I want to start with the type Vector3f is imported from com.jme3.math from jMonkeyEngine.
What I tried is:
package com.jme3.math
object Vector3f {
def apply() = new Vector3f()
def apply(x:Float, y:Float, z:Float) = new Vector3f(x,y,z)
}
When compiling this, I get errors:
Error:(8, 21) not found: type Vector3f
def apply() = new Vector3f()
When I add import com.jme3.math.Vector3f, I get warning which probably explains what I see:
Warning:(3, 22) imported `Vector3f' is permanently hidden by definition of object Vector3f in package math
How can I create a companion object for com.jme3.math.Vector3f or other types imported from Java?
That's a naming issue, you can't have both the Java class and Scala companion object with the same name there.
Either you access Java class inside companion object with the fully qualified name new com.jme3.math.Vector3f(...) or you indicate a different local name while importing it.
import com.jme3.math.{ Vector3f => JV3 }
def apply(): JV3 = new JV3()
Extra example (companion object for Java class org.apache.http.HttpClient):
import org.apache.http.client.{ HttpClient ⇒ HC }
object HttpClient {
def apply(): HC = ???
}
Or...
// No import
object HttpClient {
def apply(): org.apache.http.client.HttpClient = ???
}
Related
I want to inject dependency with Generic type using Guice. Find below example in scala which replicate the issue.
ProductModel.scala
trait BaseProduct
case class Product() extends BaseProduct
CartService.scala
class CartService[A <: BaseProduct] #Inject()(productService : ProductService[A]) {
def getCartItems = productService.getProduct
}
ProductService.scala
class ProductService[A]{
def getProduct = println("ProductService")
}
Main.scala
object Main extends App {
val injector = Guice.createInjector(new ShoppingModule)
val cartService = injector.getInstance(classOf[CartService[Product]])
cartService.getCartItems
}
class ShoppingModule extends AbstractModule with ScalaModule {
override def configure(): Unit = {
bind[BaseProduct].to(scalaguice.typeLiteral[Product])
}
}
while running this Main.scala app getting below error.
service.ProductService<A> cannot be used as a key; It is not fully specified.
I have tried binding using codingwell library. But it doesn't help to identify ProductService Type.
When you create instance of cartService at that time use typeLiteral to create instance like
val cartService = injector.getInstance(Key.get(scalaguice.typeLiteral[CartService[Product]])
if you create instance like above you don't need to create module.
Create injector using default Module (i.e. useful if you have any other bindings in default Module.scala at application level)
val appBuilder = new GuiceApplicationBuilder()
val injector = Guice.createInjector(appBuilder.applicationModule())
and if you don't have any module you can skip passing module as argument and create injector without passing any module as well like
val injector = Guice.createInjector()
What's wrong with this code:
class Trivials(s:String){
private val x = 0
}
object Trivials {
def main(args: Array[String]): Unit = {
Trivials t = new Trivials("Trivials")
}
}
Both class and object are defined in same source file, hence they are companion.
Error message is as: 'Cannot resolve symbol t'
Wrong syntax (You are using Java syntax) for object creation. In case of Scala you need not mention the type in front of the variable t it will be automatically inferred.
Trivials t = new Trivials("Trivials")
Scala syntax
val t = new Trivials("Trivials")
I'm trying to make a generic implicit provider which can create an implicit value for a given type, something in the lines of:
trait Evidence[T]
class ImplicitProvider[T] {
class Implementation extends Evidence[T]
implicit val evidence: Evidence[T] = new Implementation
}
To use this implicit, I create a val provider = new ImplicitProvider[T] instance where necessary and import from it import provider._. This works fine as long as there is just one instance. However sometimes implicits for several types are needed in one place
case class A()
case class B()
class Test extends App {
val aProvider = new ImplicitProvider[A]
val bProvider = new ImplicitProvider[B]
import aProvider._
import bProvider._
val a = implicitly[Evidence[A]]
val b = implicitly[Evidence[B]]
}
And this fails to compile with could not find implicit value for parameter and not enough arguments for method implicitly errors.
If I use implicit vals from providers directly, everything starts to work again.
implicit val aEvidence = aProvider.evidence
implicit val bEvidence = bProvider.evidence
However I'm trying to avoid importing individual values, as there are actually several implicits inside each provider and the goal is to abstract them if possible.
Can this be achieved somehow or do I want too much from the compiler?
The issue is that when you import from both objects, you're bringing in two entities that have colliding names: evidence in aProvider and evidence in bProvider. The compiler cannot disambiguate those, both because of how its implemented, and because it'd be a bad idea for implicits, which can already be arcane, to be able to do things that cannot be done explicitly (disambiguating between clashing names).
What I don't understand is what the point of ImplicitProvider is. You can pull the Implementation class out to the top level and have an object somewhere that holds the implicit vals.
class Implementation[T] extends Evidence[T]
object Evidence {
implicit val aEvidence: Evidence[A] = new Implementation[A]
implicit val bEvidence: Evidence[B] = new Implementation[B]
}
// Usage:
import Evidence._
implicitly[Evidence[A]]
implicitly[Evidence[B]]
Now, there is no name clash.
If you need to have an actual ImplicitProvider, you can instead do this:
class ImplicitProvider[T] { ... }
object ImplicitProviders {
implicit val aProvider = new ImplicitProvider[A]
implicit val bProvider = new ImplicitProvider[B]
implicit def ImplicitProvider2Evidence[T: ImplicitProvider]: Evidence[T]
= implicitly[ImplicitProvider[T]].evidence
}
// Usage
import ImplicitProviders._
// ...
I am creating a singleton object using script xyz.scala as follow :
object ChecksumCalculator {
def calcChecksum(s: String): Int = {
val cc = new ChecksumCalculator
for (c <- s)
cc.add(c.toByte)
cc.checksum
} }
When I run this as script as Scala xyz.scala ,
I am getting the error as :
01HW993798:scala tcssig$ scalac xyz.scala
xyz.scala:3: error: not found: type ChecksumCalculator
val cc = new ChecksumCalculator
^
one error found
Although I have declared the standalone object at the top, is it possible that my standalone object is not getting recognized.
Or is it due to some other error ?
In scala, singleton objects are instantiated on usage and guaranteed to be instantiated only once, hence providing strict "singleton" semantics.
Assuming that your object has method "add(b:Byte)" you could do:
CheckSumCalculator.add(c.toByte)
But given that we are in the scope of CheckSumCalculator, using this should be sufficient:
add(c.toByte)
That said, using a singleton object for mutable operations seems a bad idea.
It looks like that what you are looking for is to create instances of some class, but also have some facility method that can be called statically.
That construction has a name in Scala: A companion object
companion objects are defined by creating an object of the same name as some given class.
Translating that to this scenario, we would have:
class ChecksumCalculator {
def add(b:Byte) = ???
def checksum(): Int = ??? // or whatever type the checksum is
}
object ChecksumCalculator { // this is a companion object
def calcChecksum(s: String): Int = {
val cc = new ChecksumCalculator
s.foreach(c => cc.add(c.toByte))
cc.checksum()
}
}
I need to use an implicit ordering that has been defined in an object in a file
abc
in the following way:
object abc{
implicit def localTimeOrdering: Ordering[LocalDate] = Ordering.fromLessThan(_.isBefore(_))
}
So, I make a package object
xyz
inside a file 'package.scala' that in turn is in the package 'xyz' that has files in which I need the implicit ordering to be applicable. I write something like this:
package object xyz{
import abc._
}
It does not seem to work. If I manually write the implicit definition statement inside the package object, it works perfectly. What is the correct way to import the object (abc) such that all of its objects/classes/definitions can be used in my entire package 'xyz' ?
You cannot import the implicit conversions in that way, you will have to:
Manually write them inside the object:
package obj {
implicit def etc//
}
Or obtain them via inheritance/mixins:
package obj extends SomeClassOrTraitWithImplicits with AnotherTraitWithImplicits {
}
For this reason, you usually define your implicit conversions in traits or class definitions, that way you can do bulk import with a single package object.
The usual pattern is to define a helper trait for each case.
trait SomeClass {
// all the implicits here
}
object SomeClass extends SomeClass {}
Doing this would allow you to:
package object abc extends SomeClass with SomeOtherClass with AThirdClass {
// all implicits are now available in scope.
}