Scala "fluent" style programming

542 views Asked by At

I'm learning Scala from the book "Scala for the Impatient". One section in the book illustrates the "fluent" style of programming with the following code snippet:

object Title

class Document {
  private var useNextArgAs: Any = null
  def set(obj: Title.type): this.type = { useNextArgAs = obj; this }
  def to(arg: String) = if (useNextArgAs == Title) title = arg; else ...
}

The author then makes the following method call:

book set Title to "Scala for the Impatient"

Some questions here:

  1. Why is useNextArgAs type Any? The only type that's used in the example for useNextArgAs is a Title. Can you show a use case for using Any instead of Title?
  2. Method set returns this but the return type is this.type, not Document? Isn't this supposed to be the instance?
  3. In method to, title = arg refers to non-existent var title? Where did it come from?
1

There are 1 answers

2
harshtuna On

A possible (not entirely correct) implementation for this excercise from the book can be found (Spoiler Alert!) in github

The chapter 18 where this example comes from is labeled as "Senior Lib Designer" difficulty level. At this level a person should be well aware of re-use and extensibility issues, and consequences of mutable state in scala. This is definetely not a technic for beginners.

To OP's questions:

1) Why is useNextArgAs type Any? --- to make it support arbitrary attribute types in Document sub-classes. Document is not declared final

2) Method set returns this but the return type is this.type --- see Alvin Alexander's article below (you probably have the explanation in "Scala for the Impatient")

explicitly setting this.type as the return type of your set* methods ensures that the fluent style will continue to work in your subclasses

consider the following extension and play around with set() and to() return type and value

class Book extends Document {
  def bind :this.type = {/*do something*/; this}
}

val book = new Book
(book set Title to "Scala for the Impatient").bind

3) non-existent var title --- it is a mutable field in Document, just missing in the code snippet provided

Some extra reading on the subject: