Is it possible to cling methods from different traits?

I have the following code:

class Parameterizable{ var map: Map[String, String] = new scala.collection.immutable.HashMap() def put(entry: Tuple2[String, String]) = { map = map + entry; this } } class Query() extends Parameterizable{ override def toString = { map.isEmpty match{ case true => "" case false => "?" + map.map{case (key, value) => key + "=" + value}.mkString("&") } } } trait PageParameter extends Parameterizable{ def page(page: Int) = put(("page" -> page.toString)) def pageSize(pageSize: Int) = put(("pagesize" -> pageSize.toString)) } trait DateParameter extends Parameterizable{ def fromDate(date: java.util.Date) = put(("fromdate" -> (date.getTime()/1000L).toString())) def toDate(date: java.util.Date) = put(("todate" -> (date.getTime()/1000L).toString())) } //and other similar traits 

I would like to do something like:

 class ExtendedQuery extends Query with PageParameter with DateParameter val query = new ExtendedQuery query.page(4).pageSize(5).fromDate(new java.util.Date) 

or

 query.and().page(4).and().pageSize(5).and().fromDate(new java.util.Date) 

Is this possible in Scala?

+6
source share
1 answer

You can declare methods as returning this.type , and then return this from them:

 trait PageParameter extends Parameterizable{ def page(page: Int) : this.type = { put(("page" -> page.toString)); this } def pageSize(pageSize: Int): this.type = { put(("pagesize" -> pageSize.toString)); this } } 

At the participating site, you can associate calls as you wish. See this example:

 scala> trait Wibble { | def foo : this.type = { println("foo"); this } | } defined trait Wibble scala> trait Wobble extends Wibble { | def bar: this.type = { println("bar"); this } | } defined trait Wobble scala> trait Wubble extends Wibble { | def baz: this.type = { println("baz"); this } | } defined trait Wubble 

Now i can check it out

 scala> new Wibble with Wobble with Wubble res0: java.lang.Object with Wibble with Wobble with Wubble = $anon$1@937e20 scala> res0.bar.baz.foo bar baz foo res1: res0.type = $anon$1@937e20 
+11
source

Source: https://habr.com/ru/post/894375/


All Articles