How to initialize a trait variable that is a val - scala

I have MyObject and MyTrait:
class MyObject(private val myname: String = "") extends MyTrait {
_name = myname
def foo(myname : String) {
_name = myname
}
}
trait MyTrait {
protected var _name: String = _
def name = _name
}
This works fine as this
val myObject = new MyObject("abc")
println(myObject.name)
myObject.foo("def")
println(myObject.name)
prints
abc
def
as expected.
Problem now is that I want MyTrait._name to be a val instead of a var. But there is no way I can manage to get this to compile. Any hints appreciated.
Regards, Oliver

Here is an answer that uses the very latest cutting-edge naming conventions from Rex Kerr and Martin Odersky!
Read it on the scala-debate list. And you thought they sit around working on "higher kinds" and computing with unboxed ints.
There is a PR for the style changes, but this convention will have to wait a bit.
Doc Martin says: That does look promising. I have to experiment with it a little.
So be careful with this stuff; it's experimental and probably chemically unstable.
class MyObject(override protected val initialName: String = "") extends MyTrait {
private var myName: String = initialName
def name_=(newName: String) {
myName = newName
}
override def name = myName
}
trait MyTrait {
protected val initialName: String = "default"
def name = initialName
}
object Test extends App {
val myObject = new MyObject("abc")
println(myObject.name)
myObject.name = "def"
println(myObject.name)
}
The style guide has a section on brevity but is itself not brief. I'm sure there are answers on SO about "prefer def over val in traits" by Daniel Sobral. And don't forget to consult the one-question FAQ when you encounter init-order problems.

Related

DSL in scala using case classes

My use case has case classes something like
case class Address(name:String,pincode:String){
override def toString =name +"=" +pincode
}
case class Department(name:String){
override def toString =name
}
case class emp(address:Address,department:Department)
I want to create a DSL like below.Can anyone share the links about how to create a DSL and any suggestions to achieve the below.
emp.withAddress("abc","12222").withDepartment("HR")
Update:
Actual use case class may have more fields close to 20. I want to avoid redudancy of code
I created a DSL using reflection so that we don't need to add every field to it.
Disclamer: This DSL is extremely weakly typed and I did it just for fun. I don't really think this is a good approach in Scala.
scala> create an Employee where "homeAddress" is Address("a", "b") and "department" is Department("c") and that_s it
res0: Employee = Employee(a=b,null,c)
scala> create an Employee where "workAddress" is Address("w", "x") and "homeAddress" is Address("y", "z") and that_s it
res1: Employee = Employee(y=z,w=x,null)
scala> create a Customer where "address" is Address("a", "b") and "age" is 900 and that_s it
res0: Customer = Customer(a=b,900)
The last example is the equivalent of writing:
create.a(Customer).where("address").is(Address("a", "b")).and("age").is(900).and(that_s).it
A way of writing DSLs in Scala and avoid parentheses and the dot is by following this pattern:
object.method(parameter).method(parameter)...
Here is the source:
// DSL
object create {
def an(t: Employee.type) = new ModelDSL(Employee(null, null, null))
def a(t: Customer.type) = new ModelDSL(Customer(null, 0))
}
object that_s
class ModelDSL[T](model: T) {
def where(field: String): ValueDSL[ModelDSL2[T], Any] = new ValueDSL(value => {
val f = model.getClass.getDeclaredField(field)
f.setAccessible(true)
f.set(model, value)
new ModelDSL2[T](model)
})
def and(t: that_s.type) = new { def it = model }
}
class ModelDSL2[T](model: T) {
def and(field: String) = new ModelDSL(model).where(field)
def and(t: that_s.type) = new { def it = model }
}
class ValueDSL[T, V](callback: V => T) {
def is(value: V): T = callback(value)
}
// Models
case class Employee(homeAddress: Address, workAddress: Address, department: Department)
case class Customer(address: Address, age: Int)
case class Address(name: String, pincode: String) {
override def toString = name + "=" + pincode
}
case class Department(name: String) {
override def toString = name
}
I really don't think you need the builder pattern in Scala. Just give your case class reasonable defaults and use the copy method.
i.e.:
employee.copy(address = Address("abc","12222"),
department = Department("HR"))
You could also use an immutable builder:
case class EmployeeBuilder(address:Address = Address("", ""),department:Department = Department("")) {
def build = emp(address, department)
def withAddress(address: Address) = copy(address = address)
def withDepartment(department: Department) = copy(department = department)
}
object EmployeeBuilder {
def withAddress(address: Address) = EmployeeBuilder().copy(address = address)
def withDepartment(department: Department) = EmployeeBuilder().copy(department = department)
}
You could do
object emp {
def builder = new Builder(None, None)
case class Builder(address: Option[Address], department: Option[Department]) {
def withDepartment(name:String) = {
val dept = Department(name)
this.copy(department = Some(dept))
}
def withAddress(name:String, pincode:String) = {
val addr = Address(name, pincode)
this.copy(address = Some(addr))
}
def build = (address, department) match {
case (Some(a), Some(d)) => new emp(a, d)
case (None, _) => throw new IllegalStateException("Address not provided")
case _ => throw new IllegalStateException("Department not provided")
}
}
}
and use it as emp.builder.withAddress("abc","12222").withDepartment("HR").build().
You don't need optional fields, copy, or the builder pattern (exactly), if you are willing to have the build always take the arguments in a particular order:
case class emp(address:Address,department:Department, id: Long)
object emp {
def withAddress(name: String, pincode: String): WithDepartment =
new WithDepartment(Address(name, pincode))
final class WithDepartment(private val address: Address)
extends AnyVal {
def withDepartment(name: String): WithId =
new WithId(address, Department(name))
}
final class WithId(address: Address, department: Department) {
def withId(id: Long): emp = emp(address, department, id)
}
}
emp.withAddress("abc","12222").withDepartment("HR").withId(1)
The idea here is that each emp parameter gets its own class which provides a method to get you to the next class, until the final one gives you an emp object. It's like currying but at the type level. As you can see I've added an extra parameter just as an example of how to extend the pattern past the first two parameters.
The nice thing about this approach is that, even if you're part-way through the build, the type you have so far will guide you to the next step. So if you have a WithDepartment so far, you know that the next argument you need to supply is a department name.
If you want to avoid modifying the origin classes you can use implicit class, e.g.
implicit class EmpExtensions(emp: emp) {
def withAddress(name: String, pincode: String) {
//code omitted
}
// code omitted
}
then import EmpExtensions wherever you need these methods

Scala reflect string to singleton object

I'm looking for a way to convert a Scala singleton object given as a string (for example: package1.Main) to the actual instance of Main, so that I can invoke methods on it.
Example of the problem:
package x {
object Main extends App {
val objectPath: String = io.StdIn.readLine("Give an object: ") // user enters: x.B
// how to convert the objectPath (String) to a variable that references singleton B?
val b1: A = magicallyConvert1(objectPath)
b1.hi()
val b2: B.type = magicallyConvert2(objectPath)
b2.extra()
}
trait A {
def hi() = {}
}
object B extends A {
def extra() = {}
}
}
How can the magicallyConvert1 and magicallyConvert2 functions be implemented?
For a normal class, this can be done using something like:
val b: A = Class.forName("x.B").newInstance().asInstanceOf[A]
But I found a solution for singletons, using Java reflections:
A singleton is accesible in Java under the name:
package.SingletonName$.MODULE$
So you have to append "$.MODULE$", which is a static field.
So we can use standard Java reflections to get it.
So the solution is:
def magicallyConvert1(objectPath: String) = {
val clz = Class.forName(objectPath + "$")
val field = clz.getField("MODULE$")
val b: A = field.get(null).asInstanceOf[A]
b
}
def magicallyConvert2(objectPath: String) = {
val clz = Class.forName(objectPath + "$")
val field = clz.getField("MODULE$")
val b: B.type = field.get(null).asInstanceOf[B.type]
b
}
But it would be interesting to still see a solution with Scala-Reflect en Scala-Meta.
take a look at scalameta http://scalameta.org it does what you want and more

Existential types in Scala

Please find below a short example which puzzles me.
I must concede that I have some difficulties to manipulate existential types in Scala.
How should I solve the type mismatch line 56 ?
proposer is OK type _$1 while proposers is of type _$1 <: Individual
Thanks in advance,
Maxime.
class Individual(n: String) {
protected val name=n
var preferred: Individual = this
override def toString(): String=name
}
class Man(n: String) extends Individual(n) { }
class Woman(n: String) extends Individual(n) { }
class Marriage(m: Man, w: Woman){
private val man=m
private val woman=w
def this(w: Woman, m: Man) = this(m,w)
override def toString(): String = man+"--"+woman
}
class Matching(){
private var list: List[Marriage] = Nil
def add(m: Marriage): Unit = { list = m ::list }
override def toString(): String= {
var s: String = ""
for (elm<-list) s=s+elm+" "
return s
}
}
object Test{
protected var male = true
def main(args: Array[String]): Unit = {
val al = new Man("Al")
val bob = new Man("Bob")
val alice = new Woman("Alice")
val barbara = new Woman("Barbara")
al.preferred = alice
bob.preferred = barbara
alice.preferred = bob
barbara.preferred = al
val men = Set(al, bob)
val women = Set(alice, barbara)
val m = new Matching()
//var proposers=women
var proposers: Set[_ <:Individual] = Set[Individual]()
if (male) proposers = men
else proposers = women
while (!proposers.isEmpty) {
for(proposer <- proposers) {
val proposer=proposers.head
if (proposer.isInstanceOf[Man])
m.add(new Marriage(
proposer.asInstanceOf[Man],
proposer.preferred.asInstanceOf[Woman]
))
else
m.add(new Marriage(
proposer.asInstanceOf[Woman],
proposer.preferred.asInstanceOf[Man]
))
proposers-=proposer//There is an error here
}
}
println(m)
}
}
This code is messy. It's poorly formatted, it mixes tabs and spaces, and it uses mutability even in the most trivial of places where a functional solution requires little thought.
This code also won't scale internationally to countries where same-sex marriage is a possibility.
Working from the top down...
I suspect you'll never want to directly instantiate an Individual, only ever a Man or a Woman. So a algebraic data type makes more sense, this is done with a sealed trait and case class subtypes.
I'll also drop the preferred property, as it can lead to circular references. Dealing with this in immutable data is beyond the level I'm willing to go in this answer.
sealed trait Individual {
def name: String
override def toString(): String=name
}
//as it's a case class, `name` becomes a val,
//which implements the abstract `def name` from the trait
case class Man(name: String) extends Individual
case class Woman(name: String) extends Individual
Marriage can also be a case class, and let's drop the clumsy duplication of class parameters into vals - it's just pointless boilerplate. This is also a good time to move the auxiliary constructor to a factory method in the companion object:
case class Marriage(man: Man, woman: Woman) {
override def toString(): String = man + "--" + woman
}
object Marriage {
def apply(w: Woman, m: Man) = new Marriage(m,w)
}
Matching is almost pointless, an entire class just to wrap a List? This kind of thing made sense in pre-Generics Java, but not any more. I'll keep it anyway (for now) so I can fix up that toString implementation, which is painfully mutable and uses return for no good reason:
case class Matching(){
private var list: List[Marriage] = Nil
def add(m: Marriage): Unit = { list ::= m }
override def toString() = list.mkString(" ")
}
Finally, the "meat" of the problem. Comments are inline, but you'll note that I don't need (or use) Matching. It's replaced in its entirety by the final println
object Test{
//better name, and a val (because it never changes)
protected val menPropose = true
def main(args: Array[String]): Unit = {
// `new` not required for case classes
val al = Man("Al")
val bob = Man("Bob")
val alice = Woman("Alice")
val barbara = Woman("Barbara")
// remember how preference was removed from `Individual`?
val mprefs = Map( al -> alice, bob -> barbara )
val fprefs = Map( alice -> bob, barbara -> al )
val men = Set(al, bob)
val women = Set(alice, barbara)
// nicely immutable, and using the returned value from if/else
val proposers = if (menPropose) men else women
// no while loop, name shadowing, or mutability.
// just a simple for-comprehension
val marriages = for(proposer <- proposers) yield {
//pattern-matching beats `isInstanceOf`... every time
proposer match {
case m: Man => Marriage(m, mprefs(m))
case f: Woman => Marriage(f, fprefs(f))
}
}
println(marriages mkString " ")
}
}
There's more that can be done here, way more. What of same-sex relationships? What if two or more people share the same preference? What if someone has no preference?
I could also encode the type of someone's preference into Individual instances. But that's getting a bit more advanced.

Scala: Can I reproduce anonymous class creation with a factory method?

As far as I understand it, Scala creates an anonymous class if I create a class using the new keyword and follow the class name with a constructor:
class MyClass {
def doStuff() {
// ...
}
}
val mc = new MyClass {
doStuff()
}
The nice thing being that all the code in the constructor is in the scope of the new object.
Is there a way I can reproduce this syntax where the class is created by a factory method rather than the new keyword? i.e. make the following code work:
val mf = new MyFactory
val mc = mf.MyClass {
doStuff()
}
I can't find a way to do it but Scala has so much to it that this might be pretty easy!
Using an import as suggested by #Ricky below I can get:
val mf = MyFactory;
val mc = mf.MyClass
{
import mc._
doStuff()
}
(Where the blank line before the block is needed) but that code block is not a constructor.
You can do this, but you still have to keep the new keyword, and create the nested class as a path-dependent type:
class Bippy(x: Int) {
class Bop {
def getIt = x
}
}
val bip = new Bippy(7)
val bop = new bip.Bop
bop.getIt // yields 7
val bop2 = new bip.Bop{ override def getIt = 42 }
bop2.getIt // yields 42
I don't think it's possible. However, a common pattern is to add a parameter to factory methods which takes a function modifying the created object:
trait MyClass {
var name = ""
def doStuff():Unit
}
class Foo extends MyClass {
def doStuff() { println("FOO: " + name) }
}
trait MyClassFactory {
def make: MyClass
def apply( body: MyClass => Unit ) = {
val mc = make
body(mc)
mc
}
}
object FooFactory extends MyClassFactory {
def make = new Foo
}
You can then create and modify instance with a syntax close to your example:
val foo = FooFactory { f=>
f.name = "Joe"
f.doStuff
}
It sounds like you're just looking to mix in a trait. Instead of calling myFactoryMethod(classOf[Foo]] which ideally would do (if Scala permitted it):
new T {
override def toString = "My implementation here."
}
you can instead write
trait MyImplementation {
override def toString = "My implementation here."
}
new Foo with MyImplementation
However, if you are just looking to get the members of the new object accessible without qualification, remember you can import from any stable identifier:
val foo = new Bar
import foo._
println(baz) //where baz is a member of foo.

what's the right method to accomplish this in scala

So, I have to parallel class structures, Books and Makers. A Maker creates a book based on some file or something. We can simplify the definition of the basic Maker down to:
class Maker {
type PF = (String, Book) => Book
def apply(in: Source): Book = {
mkMap(in, parseTop)
}
def mkMap(in: Source, top: PF) {
var res = new Book
in.getLines.foreach { ln => res = top(ln, res)
}
def parseTop(line: String, book: Book): Book = {
// really makes a new Book object with changes based on the content of `line` and returns it
book
}
}
and Book looks something like this (not a case class because we want to be able to inherit it)
class Book(val title: String = "Untitled", val author: String = "No Author", val language: String = "English")
def copy(title: String = this.title, author: String = this.author, language: String = this.language) = new Book(title, author, language)
Now, I'd like to extend this to make a SpecialMaker that makes SpecialBooks. A Special Book can be defined like this:
class SpecialBook(title: String = "Untitled", author: String = "No Author", language: String = "English", val specialness: Int = 9000) extends Book(title, author, language)
def copy(title: String = this.title, author: String = this.author, language: String = this.language, specialness: Int = this.specialness) = new SpecialBook(title, author, language, specialness)
The only thing that changes in making a SpecialBook from a Book is that the parseTop function does some additional calculation to make the specialness factor, let's say like this:
class SpecialMaker {
override def parseTop(line: String, book: SpecialBook): SpecialBook = {
book.copy(specialness = book.specialness + 9000)
}
}
Obviously, that code doesn't work because that parseTop would end up assigning a SpecialBook to a Book, among other problems. What's the best way to deal with the issue in Scala? Implicit conversions? (Could something to do with type parameters work?)
If there is a design pattern that deals with this, please let me know what it's called.
My approach, so you define the return type of parseTop by parameterizing the type of Maker:
trait Maker[B <: Book] {
def parseTop(line: String, book: B): B
}
trait Book {
val title: String
val author: String
val language: String
}
case class NonSpecialBook(title: String = "Untitled", author: String = "No Author", language: String = "English") extends Book
case class SpecialBook(title: String = "Untitled", author: String = "No Author", language: String = "English", val specialness: Int = 9000) extends Book
class NonSpecialMaker extends Maker[NonSpecialBook] {
def parseTop(line: String, book: NonSpecialBook): NonSpecialBook = {
book
}
}
class SpecialMaker extends Maker[SpecialBook] {
def parseTop(line: String, book: SpecialBook): SpecialBook = {
book.copy(specialness = book.specialness + 9000)
}
}
Do you need the parseTop method in SpecialMaker to hanle SpecialBooks´s or is it supposed to make books special? Is it possible to have a trait for books and all book types inherit from that trait?
Tell me, what´s missing to fit your needs.
EDIT: (due to comment)
You can supply an implicit BookBuilder :
trait Maker[B <: Book] {
type PF = (String, B) => B
def parseTop(line: String, book: B): B
def mkMap(in: Source, top: PF)(implicit bookBuilder: {def apply(): B} ) {
var res = bookBuilder()
// ...
}
}
But that implicit BookBuilder must be implicitly in scope (or conveyed manually) everytime you use mkMap.
I don´t know when you use mkMap.