An old trick I used in my previous Java projects was to create e.g. a FileUtils class that offered helper functions for common file operations needed by my project and not covered by e.g. org.apache.commons.io.FileUtils. Therefore my custom FileUtils would extend org.apache.commons.io.FileUtils and offer all their functions as well.
Now I try to do the same in Scala but the apache helper functions are not seen through my FileUtils Scala object, what is wrong here?
import org.apache.commons.io.{ FileUtils => ApacheFileUtils }
object FileUtils extends ApacheFileUtils {
// ... additional helper methods
}
val content = FileUtils.readFileToString(new File("/tmp/whatever.txt"))
here the compiler complains that readFileToString is not a member of my Scala FileUtils but it is of ApacheFileUtils and I extend from it ...
The Scala equivalent of a class with static methods is an object, so in Scala terms, the static components of FileUtils are seen as
object FileUtils {
def readFile(s:String) = ???
...
}
And in Scala, you can't extend an object. This is illegal:
object A
object B extends A // A is not a type
Therefore object FileUtils extends ApacheFileUtils only gives you access to the class-level definitions of ApacheFileUtils (that except for the base Object methods like equals and hashCode, you have none)
You might find that Scala offers more elegant ways of providing extensions. Have a look at the 'pimp up my library' pattern for good starting point.
To apply this pattern to your example:
// definition of your "pimped" methods
import java.io.File
class RichFile(file:File) {
def readToString():String = ???
}
// companion object defines implicit conversion
object RichFile {
implicit def fileToRichFile(f:File):RichFile = new RichFile(f)
}
// Usage
import RichFile._
val content = new File("/tmp/whatever.txt").readToString
Related
I'm writing a set of implicit Scala wrapper classes for an existing Java library (so that I can decorate that library to make it more convenient for Scala developers).
As a trivial example, let's say that the Java library (which I can't modify) has a class such as the following:
public class Value<T> {
// Etc.
public void setValue(T newValue) {...}
public T getValue() {...}
}
Now let's say I want to decorate this class with Scala-style getters and setters. I can do this with the following implicit class:
final implicit class RichValue[T](private val v: Value[T])
extends AnyVal {
// Etc.
def value: T = v.getValue
def value_=(newValue: T): Unit = v.setValue(newValue)
}
The implicit keyword tells the Scala compiler that it can convert instances of Value to be instances of RichValue implicitly (provided that the latter is in scope). So now I can apply methods defined within RichValue to instances of Value. For example:
def increment(v: Value[Int]): Unit = {
v.value = v.value + 1
}
(Agreed, this isn't very nice code, and is not exactly functional. I'm just trying to demonstrate a simple use case.)
Unfortunately, Scala does not allow implicit classes to be top-level, so they must be defined within a package object, object, class or trait and not just in a package. (I have no idea why this restriction is necessary, but I assume it's for compatibility with implicit conversion functions.)
However, I'm also extending RichValue from AnyVal to make this a value class. If you're not familiar with them, they allow the Scala compiler to make allocation optimizations. Specifically, the compiler does not always need to create instances of RichValue, and can operate directly on the value class's constructor argument.
In other words, there's very little performance overhead from using a Scala implicit value class as a wrapper, which is nice. :-)
However, a major restriction of value classes is that they cannot be defined within a class or a trait; they can only be members of packages, package objects or objects. (This is so that they do not need to maintain a pointer to the outer class instance.)
An implicit value class must honor both sets of constraints, so it can only be defined within a package object or an object.
And therein lies the problem. The library I'm wrapping contains a deep hierarchy of packages with a huge number of classes and interfaces. Ideally, I want to be able to import my wrapper classes with a single import statement, such as:
import mylib.implicits._
to make using them as simple as possible.
The only way I can currently see of achieving this is to put all of my implicit value class definitions inside a single package object (or object) within a single source file:
package mylib
package object implicits {
implicit final class RichValue[T](private val v: Value[T])
extends AnyVal {
// ...
}
// Etc. with hundreds of other such classes.
}
However, that's far from ideal, and I would prefer to mirror the package structure of the target library, yet still bring everything into scope via a single import statement.
Is there a straightforward way of achieving this that doesn't sacrifice any of the benefits of this approach?
(For example, I know that if I forego making these wrappers value classes, then I can define them within a number of different traits - one for each component package - and have my root package object extend all of them, bringing everything into scope through a single import, but I don't want to sacrifice performance for convenience.)
implicit final class RichValue[T](private val v: Value[T]) extends AnyVal
Is essentially a syntax sugar for the following two definitions
import scala.language.implicitConversions // or use a compiler flag
final class RichValue[T](private val v: Value[T]) extends AnyVal
#inline implicit def RichValue[T](v: Value[T]): RichValue[T] = new RichValue(v)
(which, you might see, is why implicit classes have to be inside traits, objects or classes: they also have matching def)
There is nothing that requires those two definitions to live together. You can put them into separate objects:
object wrappedLibValues {
final class RichValue[T](private val v: Value[T]) extends AnyVal {
// lots of implementation code here
}
}
object implicits {
#inline implicit def RichValue[T](v: Value[T]): wrappedLibValues.RichValue[T] = new wrappedLibValues.RichValue(v)
}
Or into traits:
object wrappedLibValues {
final class RichValue[T](private val v: Value[T]) extends AnyVal {
// implementation here
}
trait Conversions {
#inline implicit def RichValue[T](v: Value[T]): RichValue[T] = new RichValue(v)
}
}
object implicits extends wrappedLibValues.Conversions
Let's say I want an integer that supplies a square method.
Kotlin:
fun Int.square() = this * this
usage:
println("${20.square()}")
doc:
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.
We would like to emphasize that extension functions are dispatched statically
My expectation would've been that they simply add it to the member functions of the extended class during compilation, but that is what they explicitly deny, so my next thought was it could be "sort of" like scala implicits.
Scala:
object IntExtensions{
implicit Class SquareableInt(i:Int){
def square = i*i
}
}
usage:
import IntExtensions._
and then
println(f"${20.square}")
doc:
An implicit class is desugared into a class and implicit method pairing, where the implciit method mimics the constructor of the class.
The generated implicit method will have the same name as the implicit class.
But scala implicits create a new class, that would disable the usage of this.
So ... how IS it that Kotlin extends classes? "Make callable" isn't telling me much.
In your case Kotlin just create simple utils-class with name "filename"Kt and static method "int square(int x)" (java pseudo-code)
From Java it look something like this
// filename int-utils.kt
final class IntUtilsKt {
public static int square(int x) {
return x * x;
}
}
And after this all calls to
val result = 20.square()
will be transformed (on byte-code level) to
val result = IntUtilsKt.square(20);
P.S.
You can see it yourself using IDEA action "Show Kotlin byte-code"
In Java, while type arguments are erased in runtime, it is possible to find the actual type arguments passed to a superclass:
class Derived extends Base<String> {
// ...
}
ParameterizedType type = (ParameterizedType)Derived.class.getGenericSuperclass();
Type[] args = type.getActualTypeArguments(); // gives {String.class}
While I can use the same Java reflection to Scala class, It does not catch Scala's value types:
class Base[T]
class Derived extends Base[Int]
classOf[Derived]
.getGenericSuperclass
.asInstanceOf[ParameterizedType]
.getActualTypeArguments // gives {Object.class}, not {int.class}
Is it possible to determine the value type used when extending from a generic superclass? I am loading classes from a jar file so it'd be best to achieve this only using a java.lang.Class instance.
In Java reflection you won't be able to obtain Int and other AnyVal types because they are handled specially by the compiler and if they are used generically, they will be represented by Object. However, you can use Scala reflection, and it is wholly possible to go from Java reflection to Scala reflection. Here's how:
import scala.reflect.runtime.universe._
class Base[T]
class Derived extends Base[Int]
object Main extends App {
val rm = runtimeMirror(getClass.getClassLoader) // whatever class loader you're using
val derivedSym = rm.staticClass(classOf[Derived].getName)
val baseSym = rm.staticClass(classOf[Base[_]].getName)
val TypeRef(_, _, params) = derivedSym.typeSignature.baseType(baseSym)
println(s"$derivedSym extends $baseSym[${params.mkString(", ")}]")
}
Unfortunately, unless you know exactly what you are searching for, you will have hard time finding proper documentation. I have found the answer on scala-users mailing list. Scala reflection is still experimental and, AFAIK, it will probably be superseded by a better one in future Scala versions.
I'm new to Scala (and functional programming as well) and I'm developing a plugin based application to learn and study.
I've cretead a trait to be the interface of a plugin. So when my app starts, it will load all the classes that implement this trait.
trait Plugin {
def init(config: Properties)
def execute(parameters: Map[String, Array[String]])
}
In my learning of Scala, I've read that if I want to program in functional way, I should avoid using var. Here's my problem:
The init method will be called after the class being loaded. And probably I will want to use the values from the config parameter in the execute method.
How to store this without using a var? Is there a better practice to do what I want here?
Thanks
There is more to programming in a functional way than just avoiding vars. One key concept is also to prefer immutable objects. In that respect your Plugin API is already breaking functional principles as both methods are only executed for their side-effects. With such an API using vars inside the implementation does not make a difference.
For an immutable plugin instance you could split plugin creation:
trait PluginFactory {
def createPlugin (config: Properties): Plugin
}
trait Plugin {
def execute ...
}
Example:
class MyPluginFactory extends MyPlugin {
def createPlugin (config: Properties): Plugin = {
val someValue = ... // extract from config
new MyPlugin(someValue)
}
}
class MyPlugin (someValue: String) extends Plugin {
def execute ... // using someConfig
}
You can use a val! It's basically the same thing, but the value of a val field cannot be modified later on. If you were using a class, you could write:
For example:
class Plugin(val config: Properties) {
def init {
// do init stuff...
}
def execute = // ...
}
Unfortunately, a trait cannot have class parameters. If you want to have a config field in your trait, you wont be able to set its value immediately, so it will have to be a var.
I have a number of use cases for this, all around the idea of interop between existing Java libraries and new Scala Code. The use case I've selected is the easiest I think.
Use Case:
I working on providing a JUnit Runner for some scala tests (so that I can get my lovely red / green bar in Eclipse)
The runner needs to have a constructor with a java class as a parameter. So in Scala I can do the following:
class MyRunner(val clazz: Class[Any]) extends Runner {
def getDescription(): Description
def run(notifier: RunNotifier)
}
When I use either
#RunWith(MyRunner)
object MyTestObject
or
#RunWith(MyRunner)
class MyTestClass
then the runner is indeed instantiated correctly, and is passed a suitable class object
Unfortunately what i want to do now is to "get hold of" the object MyTestObject, or create a MyTestClass, which are both Scala entities. I would prefer to use Scala Reflection, but I also want to use the standard Junit jar.
What I have done
The following Stackover flow questions were educational, but not the same problem. There were the nearest questions I could find
How to create a TypeTag manually?
Any way to obtain a Java class from a Scala (2.10) type tag or symbol?
Using Scala reflection with Java reflection
The discussion on Environments, Universes and Mirrors in http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html was good, and the similar documents on other scala reflection also helped. Mostly through it is about the Scala reflection.
I browsed the Scaladocs, but my knowledge of Scala reflection wasn't enough (yet) to let me get what I wanted out of them.
Edit:
As asked here is the code of the class that is being created by reflection
#RunWith(classOf[MyRunner])
object Hello2 extends App {
println("starting")
val x= "xxx"
}
So the interesting thing is that the solution proposed below using the field called MODULE$ doesn't print anything and the value of x is null
This solution works fine if you want to use plan old java reflection. Not sure if you can use scala reflection given all you will have is a Class[_] to work with:
object ReflectTest {
import collection.JavaConversions._
def main(args: Array[String]) {
val fooObj = instantiate(MyTestObject.getClass())
println(fooObj.foo)
val fooClass = instantiate(classOf[MyTestClass])
println(fooClass.foo)
}
def instantiate(clazz:Class[_]):Foo = {
val rm = ru.runtimeMirror(clazz.getClassLoader())
val declaredFields = clazz.getDeclaredFields().toList
val obj = declaredFields.find(field => field.getName() == "MODULE$") match{
case Some(modField) => modField.get(clazz)
case None => clazz.newInstance()
}
obj.asInstanceOf[Foo]
}
}
trait Foo{
def foo:String
}
object MyTestObject extends Foo{
def foo = "bar"
}
class MyTestClass extends Foo{
def foo = "baz"
}