scala auto convert functions / methods? - scala

I have got a class with many methods.
class C{
def f1(x:String,....):...=..
def f2(..)...
.
.
.
}
I want now that every method defined in my class is decorated with a trait of my choice automatically.
Something like to create a tricky implicit ore something what decorates every method and perhaps returns an instance of the class with decorated methods. Perhaps wrapped or modified or something. I can not describe more of the way because i dont know the way.
Do you know a way to do that?

Methods are not functions, although they will automatically be lifted when you pass them to a method that requires a function. See also http://jim-mcbeath.blogspot.com/2009/05/scala-functions-vs-methods.html
If you really have functions:
class C {
val f1 = (x: String, ...) =>
val f2 = (...) =>
...
}
and you want them to mix in a trait, like:
class C {
val f1 = new FunctionN[String, ...] with Gaga {
def apply(s: String, ...) = ...
}
val f2 = new FunctionN[...] with Gaga { ... }
...
}
the only way I can think of is submit your class to something like Scala-Refactoring: http://scala-refactoring.org/

Related

Way to enhance a class with function delegation

I have the following classes in Scala:
class A {
def doSomething() = ???
def doOtherThing() = ???
}
class B {
val a: A
// need to enhance the class with both two functions doSomething() and doOtherThing() that delegates to A
// def doSomething() = a.toDomething()
// def doOtherThing() = a.doOtherThing()
}
I need a way to enhance at compile time class B with the same function signatures as A that simply delegate to A when invoked on B.
Is there a nice way to do this in Scala?
Thank you.
In Dotty (and in future Scala 3), it's now available simply as
class B {
val a: A
export a
}
Or export a.{doSomething, doOtherThing}.
For Scala 2, there is unfortunately no built-in solution. As Tim says, you can make one, but you need to decide how much effort you are willing to spend and what exactly to support.
You can avoid repeating the function signatures by making an alias for each function:
val doSomething = a.doSomething _
val doOtherthing = a.doOtherThing _
However these are now function values rather than methods, which may or may not be relevant depending on usage.
It might be possible to use a trait or a macro-based solution, but that depends on the details of why delegation is being used.
Implicit conversion could be used for delegation like so
object Hello extends App {
class A {
def doSomething() = "A.doSomething"
def doOtherThing() = "A.doOtherThing"
}
class B {
val a: A = new A
}
implicit def delegateToA(b: B): A = b.a
val b = new B
b.doSomething() // A.doSomething
}
There is this macro delegate-macro which might just be what you are looking for. Its objective is to automatically implement the delegate/proxy pattern, so in your example your class B must extend class A.
It is cross compiled against 2.11, 2.12, and 2.13. For 2.11 and 2.12 you have to use the macro paradise compile plugin to make it work. For 2.13, you need to use flag -Ymacro-annotations instead.
Use it like this:
trait Connection {
def method1(a: String): String
def method2(a: String): String
// 96 other abstract methods
def method100(a: String): String
}
#Delegate
class MyConnection(delegatee: Connection) extends Connection {
def method10(a: String): String = "Only method I want to implement manually"
}
// The source code above would be equivalent, after the macro expansion, to the code below
class MyConnection(delegatee: Connection) extends Connection {
def method1(a: String): String = delegatee.method1(a)
def method2(a: String): String = delegatee.method2(a)
def method10(a: String): String = "Only method I need to implement manually"
// 96 other methods that are proxied to the dependency delegatee
def method100(a: String): String = delegatee.method100(a)
}
It should work in most scenarios, including when type parameters and multiple argument lists are involved.
Disclaimer: I am the creator of the macro.

Implicit conversion to make generic type available

I am using a library which has a class that has a generic type that can be quite complicated. I need to write a method that takes a parameter with the generic type that a val of the library class has, and I would like to avoid having to write out the type in the method signature. I thought I might be able to create an implicit class which adds a type to the val that I could use in the method signature, kind of like:
// This comes from a library and can't be changed
case class LibraryClass[A](a: A)
//----------------------------------
object MyCode {
val thing = LibraryClass(3)
implicit class LibraryClassWithType[A](lc: LibraryClass[A]) {
type TheType = A
}
def doStuff(something: thing.TheType): Unit = {
println(something)
}
}
This does not compile (TheType is not a member of LibraryClass). But if I wrap it in the class myself, it works
val thingWithType = LibraryClassWithType(thing)
def doStuff(something: thingWithType.TheType): Unit = {
println(something)
}
Is there something I am missing that will make this work, or is this kind of implicit conversion not valid Scala?
I haven't been able to do this sort of thing with implicits, but I have had to do something similar where I just instantiated these sorts of type holders:
case class LibraryClass[A](a: A)
object MyCode {
val thing = LibraryClass(3)
class HigherTypeHolder[A,F[A]](a: F[A]) {
type AT = A
}
val th = new HigherTypeHolder(thing)
def doStuff(something: th.AT): Unit = {
println(something)
}
}
You can do what (I think) you want like this:
implicit val thing = LibraryClass(3)
def doStuff[A](something: A)(implicit lc: LibraryClass[A])
What I don't understand is why this needs to be so complicated. Why not for example stick with your second approach, without implicits, that works, or why not just do
def doStuff[A](something: A) to begin with?

How store methods vals without recreating them every method call

I have Scala class which methods use a lot of regex. Each class method use some regex patterns.
Looking from the perspective of code modularity I should store those patterns in method:
class Bar {
def foo() {
val patt1 = "[ab]+".r
val patt2 = "[cd]+".r
/*...*/
}
}
But this approach is quite inefficient. Patterns are recompiled on each method call.
I could move them directly to class:
class Bar {
val fooPatt1 = "[ab]+".r
val fooPatt2 = "[cd]+".r
/*...*/
}
but in case when I have 30 methods it looks ugly.
I ended up with some hybrid solution using val and anonymous function:
val z = {
val patt1 = "[ab]+".r
val patt2 = "[cd]+".r
() => { /* ... */ }
}
but I am not sure if using val to store function have some drawbacks compared to def. Maybe there is other clean solution to store methods constants without polluting the class?
Using a val is perfectly fine. There might be a (very) small performance hit, but in most (99.9%) of the applications that's not a problem.
You could also create a class for the method
// The extends is not needed, although you might want to hide the Foo type
class Foo extends (() => ...) {
val patt1 = "[ab]+".r
val patt2 = "[cd]+".r
def apply() = {
...
}
}
Then in the class:
class Bar {
val foo = new Foo
}
Another solution is using traits
trait Foo {
private lazy val patt1 = "[ab]+".r
private lazy val patt2 = "[cd]+".r
def foo() = ...
}
class Bar extends Foo with ...
Note that if you have different methods like that in a single class, it can be sign that the single responsibility principle is violated. Moving them to their own class (or trait) can be a solution for that problem as well.
I would put every method with the necessary regex in it's own Trait:
class Bar extends AMethod with BMethod
trait AMethod {
private val aPattern = """\d+""".r
def aMethod(s: String) = aPattern.findFirstIn(s)
}
trait BMethod {
private val bPattern = """\w+""".r
def bMethod(s: String) = bPattern.findFirstIn(s)
}
clean
separated
easy to test (object AMethodSpec extends Properties("AMethod") with AMethod ...)
I took into account Chris comment. Putting patterns to companion object is probably the most efficient approach but very unclean when we have more methods.
EECOLOR solution is less efficient but cleaner. Traits prevents recreating patterns on each method call. Unfortunately, scala do not use same compiled pattern accross multiple class instances:
(new X).patt1==(new X).patt1 // would be false.
I've combined those two approaches and instead traits I used objects.
object X {
object method1 {
val patt1 = "a".r
}
object method2 {
val patt1 = "a".r
}
}
class X {
def method1 = {
import X.method1._
patt1
}
def method2 = {
import X.method2._
patt1
}
}
(new X).method1 == (new X).method1 // true
(new X).method2 == (new X).method2 // true
Although this approach works, I think scala should provide some solution for that problem out of box. Patterns are the simplest example. We could have other immutable objects which initialization is much more expensive.
Extracting method internals somewhere outside is still unclear. It would be nice to do it like with lazy vals. Adding one modificator should ensure that value is instance only once across all instances and methods calls. It would be something like that:
def method1 {
static val x = new VeryExpensiveObject
}

scala: how to view subclass methods with a generic instantiation

I have the following where I set information and extractors for different schemes of data:
trait DataScheme {
type Type <: List[Any]
class ExtractorMethods(ticker: String, dataList: List[Type]) {
def getDatetime(datum: Type): Date = new Date(datum(columnIndex(Names.datetime)).toString)
def upperDatum(date: Date): Type = dataList.minBy(datum => getDatetime(datum) >= date)
def lowerDatum(date: Date): Type = dataList.maxBy(datum => getDatetime(datum) <= date)
}
}
trait IndexScheme extends DataScheme {
type Type = (Date, Double, Double, Double, Double, Long)
class ExtractorMethods(ticker: String, dataList: List[Type]) extends super.ExtractorMethods(ticker: String, dataList: List[Type]){
def testing12(int: Int):Int = 12
val test123 = 123
}
}
I want anything extending DataScheme to use its ExtractorMethods methods (e.g. lowerDatum) but also have its own methods (e.g. testing12).
There is a class definition for lists of data elements:
class Data[+T <: DataScheme](val ticker: String, val dataList: List[T#Type], val isSorted: Boolean)
(implicit m: Manifest[T], mm: Manifest[T#Type]) extends Symbols {
def this(ticker: String, dataList: List[T#Type])(implicit m: Manifest[T], mm: Manifest[T#Type]) = this(ticker, dataList, false)(m: Manifest[T], mm: Manifest[T#Type])
val dataScheme: T
val extractorMethods = new dataScheme.ExtractorMethods(ticker, dataList.asInstanceOf[List[dataScheme.Type]])
}
A Data class should make accessible the methods in ExtractorMethods of the scheme so they can be used in the main program through the instance of Data that has been defined. For example if sortedData is an instance of Data[IndexScheme], the following works:
val lowerDatum = sortedData.extractorMethods.lowerDatum(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2010-03-31 00:00:00"))
but this does not:
val testing = sortedData.extractorMethods.testing12(123)
because 'testing 123 is not a member of sortedData.dataScheme.extractorMethods'. So my question is how can the subclasses of ExtractorMethods in the subtraits of DataScheme like IndexScheme be made accessible? How is it possible using Manifests and TypeTags? Thanks.
So you want the generic class Data[DataScheme] or Data[IndexScheme] to have access to the methods of whichever type Data has been parameterised with. You've tried to do this several different ways, from the evidence in your code.
To answer your last question - manifests can't help in this particular case and TypeTags are only part of the answer. If you really want to do this, you do it with mirrors.
However, you will have to make some changes to your code. Scala only has instance methods; there are no such things as static methods in Scala. This means that you can only use reflection to invoke a method on an instance of a class, trait or object. Your traits are abstract and can't be instantiated.
I can't really tell you how to clean up your code, because what you have pasted up here is a bit of a mess and is full of different things you have tried. What I can show you is how to do it with a simpler set of classes:
import scala.reflect.runtime.universe._
class t1 {
class Methods {
def a = "a"
def b = "b"
}
def methods = new Methods
}
class t2 extends t1 {
class Methods extends super.Methods {
def one = 1
def two = 2
}
override def methods = new Methods
}
class c[+T <: t1](implicit tag: TypeTag[T]) {
def generateT = {
val mirror = runtimeMirror(getClass.getClassLoader)
val cMirror = mirror.reflectClass(typeOf[T].typeSymbol.asClass)
cMirror.reflectConstructor(typeOf[T].declaration(nme.CONSTRUCTOR).asMethod)
}
val t = generateT().asInstanceOf[T]
}
val v1 = new c[t1]
val v2 = new c[t2]
If you run that, you'll find that v1.t.methods gives you a class with only methods a and b, but v2.t.methods gives a class with methods one and two as well.
This really is not how to do this - reaching for reflection for this kind of job shows a very broken model. But I guess that's your business.
I stick by what I said below, though. You should be using implicit conversions (and possibly implicit parameters) with companion objects. Use Scala's type system the way it's designed - you are fighting it all the way.
ORIGINAL ANSWER
Well, I'm going to start by saying that I would never do things the way you are doing this; it seems horribly over-complicated. But you can do what you want to do, roughly the way you are doing it, by
Using mixins
Moving the extractorMethods creation code into the traits.
Here's a greatly simplified example:
trait t1 {
class Methods {
def a = "a"
def b = "b"
}
def methods = new Methods
}
trait t2 extends t1 {
class Methods extends super.Methods {
def one = 1
def two = 2
}
override def methods = new Methods
}
class c1 extends t1
val v1 = new c1
// v1.methods.a will return "a", but v1.methods.one does not exist
class c2 extends c1 with t2
val v2 = new c2
// v2.methods.a returns "a" and v2.methods.one returns 1
I could replicate your modus operandi more closely by defining c1 like this:
class c1 extends t1 {
val myMethods = methods
}
in which case v1.myMethods would only have methods a and b but v2.myMethods would have a, b, one and two.
You should be able to see how you can adapt this to your own class and trait structure. I know my example doesn't have any of your complex type logic in it, but you know better than I what you are trying to achieve there. I'm just trying to demonstrate a simple mechanism.
But dude, way to make your life difficult...
EDIT
There are so many things I could say about what is wrong with your approach here, both on the small and large scale. I'm going to restrict myself to saying two things:
You can't do what you are trying to do in the Data class because it is abstract. You cannot force Scala to magically replace an uninitialised, abstract method of a non-specific type with the specific type, just by littering everything with Type annotations. You can only solve this with a concrete class which provides the specific type.
You should be doing this with implicit conversions. Implicits would help you do it the wrong way you seem fixated on, but would also help you do it the right way. Oh, and use a companion object, either for the implicits or to hold a factory (or bot).

Is there an easy way to chain java setters that are void instead of return this

I have a bunch of auto-generated java code that I will be calling in scala. Currently all of the objects were generated with void setters instead of returning this which makes it really annoying when you need to set a bunch of values (I'm not going to use the constructor by initializing everything since there's like 50 fields). For example:
val o = new Obj()
o.setA("a")
o.setB("b")
o.setC("c")
It would be really cool if I could do something like this
val o = with(new Obj()) {
_.setA("a")
_.setB("b")
_.setC("c")
}
I can't use andThen with anon functions since they require objects to be returned. Am I stuck with the current way I'm doing things or is there some magic I'm not aware of.
Sure, you can use tap (the Kestrel combinator), which you presently have to define yourself:
implicit class Tapper[A](val a: A) extends AnyVal {
def tap[B](f: A => B): A = { f(a); a }
def taps[B](fs: A => B*): A = { fs.map(_(a)); a }
}
It works like so:
scala> "salmon".taps(
| println,
| println
| )
salmon
salmon
res2: String = salmon
Note also
val myFavoriteObject = {
val x = new Obj
x.setA("a")
}
will allow you to use a short name to do all the setting while assigning to a more meaningful name for longer-term use.
You can use an implicit converter from/to a wrapper class that allows chaining.
Something like:
case class ObjWrapper(o: Obj) {
def setA(a: String) = { o.setA(a); this }
def setB(b: String) = { o.setB(b); this }
def setC(c: String) = { o.setC(c); this }
}
implicit def wrapped2Obj(ow: ObjWrapper): Obj = ow.o
ObjWrapper(myObj).setA("a").setB("b").setC("c")
Actually you don't even need the implicit converter since those method have been called on myObj.
Take a look at Scalaxy/Beans. Note however that it's using macros, so it should be considered experimental.