package Controls
object TestBreak extends App {
def values = {
x1 = x
y1 = y
}
val (x, y) = (1, 2)
values
var (x1, y1) = (2, 3)
println((x, y))
println((x1, y1))
}
I could see here, the program is Executing successfully without any error.
When i call method values ,even before the intialization of variables x1,y1,..
How does scala handles this case ?
How compilation of code is taking palce ?
App extends DelayedInit
As App extends DelayedInit and Main extends App. Code in the Main constructor executes as part of delayed init. Before jumping into how delayed init works, Lets see the differnce between constructor variable declaration and method variable declaration.
scala> class A {
| def a(): Unit = { println(b) }
| val b = 1
| }
defined class A
In the above example b is declared later and function a() is declared first. As it the constructor of the class Compiler accepts it.
scala> def x: Int = {
| def y: Int = z
| val z = 1
| y
| }
<console>:12: error: forward reference extends over definition of value z
def y: Int = z
^
In the above case compiler complains saying that its a forward reference.
Delayed Init is deprecated
Classes and objects (but note, not traits) inheriting the DelayedInit marker trait will have their initialization code rewritten as follows: code becomes delayedInit(code).
Initialization code comprises all statements and all value definitions that are executed during initialization.
Example:
trait Helper extends DelayedInit {
def delayedInit(body: => Unit) = {
println("dummy text, printed before initialization of C")
body // evaluates the initialization code of C
}
}
class C extends Helper {
println("this is the initialization code of C")
}
object Test extends App {
val c = new C
}
Should result in the following being printed:
dummy text, printed before initialization of C
this is the initialization code of C
Related
I have a use case similar to the situation following:
trait A {
implicit val x = "hello"
}
class B {
// somehow bring x into scope here???
def run(x: Int)(implicit y: String) = y + x
}
println((new B).run(3))
I understand that I need to bring x defined in the trait in the implicit scope of B. I've already tried the following:
# attempt 1 #
class B extends A { .... } /// doesn't work
# attempt 2 #
class B extends A {
val x1 = implicitly[String] /// doesn't work either
def run(x: Int)(implicit y: String) = y + x
}
Please explain what am I missing here (or, point me to relevant theory topic which I can study, fairly new to scala).
The value of 'implicit y' will be resolved in your println-line where it is not available. You are making the variable implicitly available within the body of the class, but resolution of implicit String is not needed there.
Implicit isn't magic; if you can't reach the implicit variable explicitly then so can't the compiler.
What problem are you really trying to solve?
Wrap your whole code in a object and extend trait A in class B :
object P {
trait A {
implicit val x = "hello"
}
class B extends A {
def run(y: Int) = y + x
}
def f = println(new B().run(3))
}
Output :
scala> P.f
3hello
I have the following code in scala:
trait A {
val foo: String => Int = { in =>
in.toInt
}
}
trait B extends A {
def bar(a: String) = {
foo(a)
}
}
class C(a: String) {
self: B =>
val b = bar(a)
}
val x = new C("34") with B
During instantiation of x I get NPE. Couldn't figure out why.
edit
NOTE: Can not figure out why foo of A trait doesn't get initialized
Please refer to the http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html.
The only addition to this is that self-type makes class C abstract. So actually you do:
abstract class C(a: String) {
def bar(a: String): Int
val b = bar(a)
}
val x = new C("34") with B
You can try to replace it in your code and see same result. Some more info here.
In short: the linearization of new C with B will be (B <- A) <- C, so initalization is C -> (A -> B). Please refer to Class Initialization section section:
After the superclass constructor is executed, the constructors for each mixin trait are executed. Since they are executed in right-to-left order within the linearization, but the linearization is created by reversing the order of the traits, this means the constructors for the mixin traits are executed in the order that they appear in the declaration for the class. Remember, however, that when mixins share hierarchy, the order of execution may not be quite the same as how the mixins appear in the declaration.
In your case new C("34") with B equals to class K extends C("34") with B; new K. Note that self type of class C doesn't affect the initialization order.
Simplified example:
scala> trait C {def aa: String; println(s"C:$aa")}
defined trait C
scala> trait D {val aa = "aa"; println(s"D:$aa")}
defined trait D
scala> new C with D
C:null
D:aa
res19: C with D = $anon$1#2b740b6
Solution: If your foo is placed in third party library (so you can't make it lazy), you may just use mix-in instead of self-type or at least mix A into the C class:
trait A {
val foo: String => Int = { in =>
in.toInt
}
}
trait B extends A {
def bar(a: String) = {
foo(a)
}
}
class C(a: String) extends A {
self: B =>
val b = bar(a)
}
val x = new C("34") with B
The short answer on why you get a NullPointerException is, that initialization of C requires initializing b, which invokes the method stored in val foo, which is not initialized at this point.
Question is, why is foo not initialized at this point? Unfortunately, I cannot fully answer this question, but I'd like to show you some experiments:
If you change the signature of C to extends B, then B, as the superclass of C is instantiated before, leading to no exception being thrown.
In fact
trait A {
val initA = {
println("initializing A")
}
}
trait B extends A {
val initB = {
println("initializing B")
}
}
class C(a: String) {
self: B => // I imagine this as C has-a B
val initC = {
println("initializing C")
}
}
object Main {
def main(args: Array[String]): Unit ={
val x = new C("34") with B
}
}
prints
initializing C
initializing A
initializing B
while
trait A {
val initA = {
println("initializing A")
}
}
trait B extends A {
val initB = {
println("initializing B")
}
}
class C(a: String) extends B { // C is-a B: The constructor of B is invoked before
val initC = {
println("initializing C")
}
}
object Main {
def main(args: Array[String]): Unit ={
val x = new C("34") with B
}
}
prints
initializing A
initializing B
initializing C
As you can see, the initialization order is different. I imagine the dependency-injection self: B => to be something like a dynamic import (i.e., putting the fields of an instance of B into the scope of C) with a composition of B (i.e., C has-a B). I cannot prove that it is solved like this, but when stepping through with IntelliJ's debugger, the fields of B are not listed under this while still being in the scope.
This should answer the question on why you get a NPE, but leaves the question open on why the mixin is not instantiated first. I cannot think of problems that may occur otherwise (since extending the trait does this basically), so this may very well be either a design choice, or noone thought about this use case. Fortunately, this will only yield problems during instantiation, so the best "solution" is probably to not use mixed-in values during instantiation (i.e., constructors and val/var members).
Edit: Using lazy val is also fine, so you can also define lazy val initC = {initB}, because lazy val are not executed until they are needed. However, if you do not care about side effects or performance, I would prefer def to lazy val, because there is less "magic" behind it.
Declare A.foo to be a lazy val.
The following code throws IllegalArgumentException:
trait T{
val x: Long
require(x > 0)
}
object T extends App{
val y = new T{ val x = 42L }
}
while the following does not:
trait T{
def x(): Long
require(x() > 0)
}
object T extends App{
val y = new T{ def x() = 42L }
}
Why is that? When is require() called? Why is the val even defined at that point?
Because def declares a method, which is put in the class by the compiler, so it exists as soon as it is compiled. In order to return something, a method has to run through to the point at which it actually returns something, so there is no problem in your second example.
val declares an "immutable value", although it still has to be initialised, before which point it holds the default value for its type - in this case, 0. This initialisation takes place after the constructor of trait T runs, unless you change your example to use early initialization:
val y = new { val x = 42L } with T
I am not able to access the class constructor parameter in the body of the function. In Scala the constructor parameter becomes the class member with appropriate get/set defined.
But in the below example, i am not able to refer to the constructor parameter 'p'. Is there something i am doing wrong? do i need to put a prefix?
abstract class MyFunc(in: Int) extends Function1[Int, Boolean] {
val x : Int = 10
}
val dunc = new MyFunc(10) {
def apply(p: Int): Boolean = {
p % in == 0 << compilation error. 'in' value not found
// p % x == 0 << compiles fine
}
}
I am able to access an explicitly defined member variable but not the constructor defined variable. Why?
By default constructor parameters are private: so they are visible only in class itself. But you change this behaviour:
abstract class MyFunc(protected val in: Int) extends Function1[Int, Boolean] {
val x : Int = 10
}
Following is a Scala class with constructors. My questions are marked with ****
class Constructors( a:Int, b:Int ) {
def this() =
{
this(4,5)
val s : String = "I want to dance after calling constructor"
//**** Constructors does not take parameters error? What is this compile error?
this(4,5)
}
def this(a:Int, b:Int, c:Int) =
{
//called constructor's definition must precede calling constructor's definition
this(5)
}
def this(d:Int)
// **** no equal to works? def this(d:Int) =
//that means you can have a constructor procedure and not a function
{
this()
}
//A private constructor
private def this(a:String) = this(1)
//**** What does this mean?
private[this] def this(a:Boolean) = this("true")
//Constructors does not return anything, not even Unit (read void)
def this(a:Double):Unit = this(10,20,30)
}
Could you please answer my questions in the **** above? For example Constructors does not take parameters error? What is this compile error?
Ans 1:
scala> class Boo(a: Int) {
| def this() = { this(3); println("lol"); this(3) }
| def apply(n: Int) = { println("apply with " + n) }
| }
defined class Boo
scala> new Boo()
lol
apply with 3
res0: Boo = Boo#fdd15b
First this(3) is a delegation to primary constructor. The second this(3) invokes this object's apply method i.e. expands to this.apply(3). Observe the above example.
Ans 2:
= is optional in constructor definitions as they don't really return anything. They have different semantics from regular methods.
Ans 3:
private[this] is called object-private access modifier. An object cannot access other object's private[this] fields even though they both belong to the same class. Thus it's stricter than private. Observe the error below:
scala> class Boo(private val a: Int, private[this] val b: Int) {
| def foo() {
| println((this.a, this.b))
| }
| }
defined class Boo
scala> new Boo(2, 3).foo()
(2,3)
scala> class Boo(private val a: Int, private[this] val b: Int) {
| def foo(that: Boo) {
| println((this.a, this.b))
| println((that.a, that.b))
| }
| }
<console>:17: error: value b is not a member of Boo
println((that.a, that.b))
^
Ans 4:
Same as Ans 2.
Related to question 2 is:
Scala Auxilliary Constructor behavior
This is causing the error, the lack of (default) parameters for int b and int c throws called constructor's definition must precede calling constructor's definition