So I'm reading the Scala for the Impatient book and one of the examples it uses is a Logger
trait that essentially prints a String
to some stream. In the example, it has a trait ConsoleLogger
(which extends Logger
) that prints the message out to stdout
and ShortLogger
(also extends Logger
) that simply truncates the string if the length is too long. To change the maximum length of ShortLogger
the book proposes uses an anonymous subclass, something like:
val acct = new SavingsAccount with ConsoleLogger with ShortLogger {
val maxLength = 20
}
Where ShortLogger
is a trait with an abstract maxLength: Int
field and SavingsAccount
is defined as
class SavingsAccount extends Account with Logged { ... }
Which makes sense to me (kind of). I'm assuming the construction order is:
Logger
gets constructed first (since it is a super-trait ofConsoleLogger
),ConsoleLogger
ShortLogger
Account
SavingsAccount
.- Then we have the anonymous subclass construction where we define the abstract
maxLength = 20
.
However, later on in the book, it gives a new Logger
sub-trait:
trait FileLogger extends Logger {
val filename: String
val out = new PrintStream(filename)
def log(msg: String) { out.println(msg); out.flush() }
}
val acct = new SavingsAccont with FileLogger {
val filename = "myapp.log" // Does not work
}
It says it does not work due to the construction order. They propose the modification:
val acct = new {
val filename: "myapp.log"
} with SavingsAccount with FileLogger
However, this definition seems to be similar to the one above with maxLength
, so what am I missing between the above example and the bottom example?