coming from my other question is there a way to get by-name-parameters for constructors working? I need a way to provide a code-block which is executed on-demand/lazy/by-name inside an object and this code-block must be able to access the class-methods as if the code-block were part of the class.
Following Testcase fails:
package test
class ByNameCons(code: => Unit) {
def exec() = {
println("pre-code")
code
println("post-code")
}
def meth() = println("method")
def exec2(code2: => Unit) = {
println("pre-code")
code2
println("post-code")
}
}
object ByNameCons {
def main(args: Array[String]): Unit = {
val tst = new ByNameCons {
println("foo")
meth() // knows meth() as code is part of ByNameCons
}
tst.exec() // ByName fails (executed right as constructor)
println("--------")
tst.exec2 { // ByName works
println("foo")
//meth() // does not know meth() as code is NOT part of ByNameCons
}
}
}
Output:
foo
method
pre-code
post-code
--------
pre-code
foo
post-code
I dont know why, but it appears that using {} or () when creating the class changes the behavior. Using the following class,
Now instead if defined another way,
as desired. It seems as if in the first notation, the compiler is interpreting the brackets as a block to be evaluated to
Unit
, instead of an anonymous function which, when called, evaluates toUnit
.FWIW, using ({ ... }) also works fine.
This is because when you're making an instance like this:
.. you're actually creating an anonymous class, like in java. The above code is the same as:
.. while the correct syntax for passing by-name is:
You cant omit parentheses the same way for constructors as with functions.
Thought it is probably just easier to do this: