What class is this Builder pattern extending? - scala

I found an interesting scala implementation of Builder pattern, but I can't understand what a few lines mean:
case class Built(a:Int, b:String){}
trait Status
trait Done extends Status
trait Need extends Status
class Builder[A<:Status,B<:Status] private(){
private var built = Built(0,"")
def setA(a0:Int)={
built = built.copy(a=a0)
this.asInstanceOf[Builder[Done,B]]
}
def setB(b0: String) = {
built = built.copy(b = b0)
this.asInstanceOf[Builder[A,Done]]
}
def result(implicit ev: Builder[A,B] <:< Builder[Done,Done]) = built
}
object Builder{
def apply() = new Builder[Need,Need]
}
1) What does private() mean in class Builder[A<:Status,B<:Status] private() class declaration?
2) What is the meaning of implicit ev: Builder[A,B] <:< Builder[Done,Done] in result function?

1)
The private means that the primary constructor for Builder can not be accessed from outside.
Since there are no other constructors, the only way to get an instance is through the companion object with the apply method.
Example:
val builder = Builder()
2)
You have methods in Builder to set both parameters for the Built case-class.
The method result gives you the constructed Built-instance. The evidence makes sure that you have set both parameters and will not allow you to create an instance if you didn't do it.
Example (I did not test this, so please correct me if I am wrong):
val builderA = Builder().setA(3)
val resultA = builderA.result //should not compile because this is Builder[Done, Need]
val builderAB = builderA.setB("hello") //now this is Builder[Done, Done]
val resultAB = builderAB.result //should compile and yield Built(3, "hello")

For your first question, the keyword private in this position means the constructor for the class is private.

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.

scala use template type to resolve sub class

I am fairly new to Scala and trying to do some code reuse. I have two enums AB and AC, both extend A which is a trait with some common methods.
object AB extends A[AB]{
val X = Value("x")
}
object AC extends A[AC]{
val Y = Value("y")
}
trait A[T] extends Enumeration{
def getProperty(prop: T.Value): String = {
//some code that uses prop.toString
}
I am trying to have a getProperty method that will restrict users to only Enums from the enumeration that it is being called upon.
if I call AB.getProperty() than i should be able to pass only X. if I call AC.getProperty than I should be able to pass only Y
If I have to redesign my classes that is fine. Please let me know how I can achieve this.
Thanks in advance
I am not sure what ConfigProperties is in your code, and why you need the type parameters, but the answer to your question is, declare the parameter type in geProperty as Value -> getProperty(prop: Value).
Value is a nested abstract class in Enumeration, so it will be expanded by the compiler respectively to AB.Value and XY.Value, depending on the instance. A simplified example which you can test in the REPL:
object AB extends A {
val A = Value('A')
val B = Value('B')
}
object XY extends A {
val X = Value('X')
val Y = Value('Y')
}
trait A extends Enumeration {
def getProperty(prop: Value): String = {
//some code that uses prop.toString
prop.toString()
}
}
AB.getProperty(AB.A) // OK
XY.getProperty(XY.Y) // Also OK
// AB.getProperty(XY.X) <- this won't compile
// Error:(21, 20) type mismatch;
// found : A$A238.this.XY.Value
// required: A$A238.this.AB.Value
// AB.getProperty(XY.X)
//

Proxy class support

Is there Scala way for runtime generation of proxy classes? not DynamicProxy but runtime types that extend provided class/interface and pass all calls through provided callback.
Java world uses cglib/javassist for that, but what is the best way to proxy in Scala?
def makeProxy[T](interceptor: Interceptor, implicit baseClass: Manifest[T]): T
Google says Scala macros can be used for this but I am unsure how.
Here is an example how (more-less) to do something like that with macro:
def testImpl[T : c.WeakTypeTag](c: Context): c.Expr[Any] = {
import c.universe._
val className = newTypeName(weakTypeTag[T].tpe.typeSymbol.name.toString) //not best way
val m = weakTypeOf[T].declarations.iterator.toList.map(_.asMethod) //`declaration` takes only current; `members` also takes inherited
.filter(m => !m.isConstructor && !m.isFinal).map { m => //all reflection info about method
q"""override def ${m.name} = 9""" //generating new method
}
c.Expr { q"""new $className { ..$m } """}
}
def t[T] = macro testImpl[T]
class Aaa{ def a = 7; def b = 8}
scala> t[Aaa].a
res39: Int = 9
scala> t[Aaa].b
res40: Int = 9
All such macro works only if overriden methods are not final as they can't change types (as it works in compile-time) - only create new and inherit. This example doesn't process classes with non-empty constructors and many other things. m here is instance of MethodSymbol and gives you full scala-style reflection about input class' method. You need only generate correct AST in response.
To read more about that:
macroses: http://docs.scala-lang.org/overviews/macros/overview.html
scala's runtime-reflection http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html
q"asiquotes" : http://docs.scala-lang.org/overviews/quasiquotes/expression-details.html
Another solution would be:
scala> def getClasss[T: ClassTag] = classTag[T].runtimeClass
getClasss: [T](implicit evidence$1: scala.reflect.ClassTag[T])Class[_]
Using this instance you can apply any asm/cglib/javassist or even DynamicProxy to it.

Scala syntactic sugar for transparently invoking a unary apply on a companion object

class OpenNLPAnnotator extends ThreadLocal[OpenNLPAnnotatorInstance] {
override def initialValue = new OpenNLPAnnotatorInstance
}
object OpenNLPAnnotator {
private lazy val ann_ = new OpenNLPAnnotator
private def ann = ann_
def apply = ann.get()
}
Is there any way for me to get the TLV by doing OpenNLPAnnotator.someMethodOnTheTLV ? I have to write OpenNLPAnnotator.apply.someMethodOnTheTLV
edit
Based on the answers below i'm thinking something like this would be nicest
object OpenNLPAnnotator {
private lazy val ann_ = new OpenNLPAnnotator
private def ann = ann_
def apply() = ann.get()
def annotator = ann.get
}
Then I could just do annotator.whatever.
That would require an import of course, so unless I put it in a package object it's swings and round-a-bouts. Though I haven't used package objects yet and do not understand the ins and outs.
The only way to call apply method implicitly is to add parentheses after object name like this:
OpenNLPAnnotator().someMethodOnTheTLV
But you have to change apply method declaration (add parentheses):
def apply() = ann.get()
Nasty hack
You could create an implicit conversion from OpenNLPAnnotator.type to OpenNLPAnnotator like this:
implicit def nastyHack(o: OpenNLPAnnotator.type): OpenNLPAnnotator = o.apply
So you could call all methods of OpenNLPAnnotator on companion object.
OpenNLPAnnotator.someMethodOnTheTLV will be converted to this:
nastyHack(OpenNLPAnnotator).someMethodOnTheTLV
Note (in response to your edit):
You could rename apply method while importing it:
import OpenNLPAnnotator.{apply => annotator}
You have two options:
Wait for me to rewrite autoproxy using macros (it'll be done around the same time that scala 2.11.0-RC1 is released)
Use a different pattern!
Did you know that singletons can inherit from their companions?
class OpenNLPAnnotator extends ThreadLocal[OpenNLPAnnotatorInstance] {
override def initialValue = new OpenNLPAnnotatorInstance
}
object OpenNLPAnnotator extends OpenNLPAnnotator {
def apply = this.get()
}

Scala - new vs object extends

What is the difference between defining an object using the new operator vs defining a standalone object by extending the class?
More specifically, given the type class GenericType { ... }, what is the difference between val a = new GenericType and object a extends GenericType?
As a practical matter, object declarations are initialized with the same mechanism as new in the bytecode. However, there are quite a few differences:
object as singletons -- each belongs to a class of which only one instance exists;
object is lazily initialized -- they'll only be created/initialized when first referred to;
an object and a class (or trait) of the same name are companions;
methods defined on object generate static forwarders on the companion class;
members of the object can access private members of the companion class;
when searching for implicits, companion objects of relevant* classes or traits are looked into.
These are just some of the differences that I can think of right of the bat. There are probably others.
* What are the "relevant" classes or traits is a longer story -- look up questions on Stack Overflow that explain it if you are interested. Look at the wiki for the scala tag if you have trouble finding them.
object definition (whether it extends something or not) means singleton object creation.
scala> class GenericType
defined class GenericType
scala> val a = new GenericType
a: GenericType = GenericType#2d581156
scala> val a = new GenericType
a: GenericType = GenericType#71e7c512
scala> object genericObject extends GenericType
defined module genericObject
scala> val a = genericObject
a: genericObject.type = genericObject$#5549fe36
scala> val a = genericObject
a: genericObject.type = genericObject$#5549fe36
While object declarations have a different semantic than a new expression, a local object declaration is for all intents and purpose the same thing as a lazy val of the same name. Consider:
class Foo( name: String ) {
println(name+".new")
def doSomething( arg: Int ) {
println(name+".doSomething("+arg+")")
}
}
def bar( x: => Foo ) {
x.doSomething(1)
x.doSomething(2)
}
def test1() {
lazy val a = new Foo("a")
bar( a )
}
def test2() {
object b extends Foo("b")
bar( b )
}
test1 defines a as a lazy val initialized with a new instance of Foo, while test2 defines b as an object extending Foo.
In essence, both lazily create a new instance of Foo and give it a name (a/b).
You can try it in the REPL and verify that they both behave the same:
scala> test1()
a.new
a.doSomething(1)
a.doSomething(2)
scala> test2()
b.new
b.doSomething(1)
b.doSomething(2)
So despite the semantic differences between object and a lazy val (in particular the special treatment of object's by the language, as outlined by Daniel C. Sobral),
a lazy val can always be substituted with a corresponding object (not that it's a very good practice), and the same goes for a lazy val/object that is a member of a class/trait.
The main practical difference I can think of will be that the object has a more specific static type: b is of type b.type (which extends Foo) while a has exactly the type Foo.