From 925c713ca4c6368fd389633fb61ed58e1209ad4b Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 23 Nov 2013 16:31:55 +0100 Subject: [PATCH 1/2] adds Gemfile as recommended by Github https://help.github.com/articles/using-jekyll-with-pages --- Gemfile | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Gemfile diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000000..3a1ebf3064 --- /dev/null +++ b/Gemfile @@ -0,0 +1,2 @@ +source 'https://rubygems.org' +gem 'github-pages' \ No newline at end of file From f9fbe876203d0328f8332ae8d09d783a4584ad4a Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sat, 23 Nov 2013 16:55:55 +0100 Subject: [PATCH 2/2] fixes https://github.com/scala/scala.github.com/pull/270 --- tutorials/FAQ/finding-symbols.md | 6 +- tutorials/FAQ/initialization-order.md | 214 +++++++++++++------------- 2 files changed, 106 insertions(+), 114 deletions(-) diff --git a/tutorials/FAQ/finding-symbols.md b/tutorials/FAQ/finding-symbols.md index a583f7a0aa..696fa9b6cf 100644 --- a/tutorials/FAQ/finding-symbols.md +++ b/tutorials/FAQ/finding-symbols.md @@ -6,7 +6,7 @@ disqus: true partof: FAQ num: 1 -outof: 8 +outof: 9 --- Let's divide the operators, for the purpose of teaching, into **four categories**: @@ -36,7 +36,7 @@ So, let's see them. Keywords/reserved symbols ------------------------- -There are a few symbols in Scala that are special and cannot be defined or used used as method names. +There are a few symbols in Scala that are special and cannot be defined or used used as method names. Two of them are considered proper keywords, while others are just "reserved". They are: // Keywords @@ -65,7 +65,7 @@ These are all _part of the language_, and, as such, can be found in any text that properly describe the language, such as [Scala Specification][1](PDF) itself. -The last one, the underscore, deserve a special description, because it is +The last one, the underscore, deserve a special description, because it is widely used, and has different meanings depending on the context. Here's a sample: import scala._ // Wild card -- all of Scala is imported diff --git a/tutorials/FAQ/initialization-order.md b/tutorials/FAQ/initialization-order.md index 184c295528..73f01ec09e 100644 --- a/tutorials/FAQ/initialization-order.md +++ b/tutorials/FAQ/initialization-order.md @@ -11,31 +11,29 @@ num: 9 ## Example To understand the problem, let's pick the following concrete example. -```scala -abstract class A { - val x1: String - val x2: String = "mom" - - println("A: " + x1 + ", " + x2) -} -class B extends A { - val x1: String = "hello" - - println("B: " + x1 + ", " + x2) -} -class C extends B { - override val x2: String = "dad" - - println("C: " + x1 + ", " + x2) -} -``` + abstract class A { + val x1: String + val x2: String = "mom" + + println("A: " + x1 + ", " + x2) + } + class B extends A { + val x1: String = "hello" + + println("B: " + x1 + ", " + x2) + } + class C extends B { + override val x2: String = "dad" + + println("C: " + x1 + ", " + x2) + } + Let's observe the initialization order through the Scala REPL: -``` -scala> new C -A: null, null -B: hello, null -C: hello, dad -``` + + scala> new C + A: null, null + B: hello, null + C: hello, dad Only when we get to the constructor of `C` are both `x1` and `x2` initialized. Therefore, constructors of `A` and `B` risk running into `NullPointerException`s. @@ -56,15 +54,14 @@ There is a compiler flag which can be useful for identifying this situation: It is inadvisable to use this flag outside of testing. It adds significantly to the code size by putting a wrapper around all potentially uninitialized field accesses: the wrapper will throw an exception rather than allow a null (or 0/false in the case of primitive types) to silently appear. Note also that this adds a *runtime* check: it can only tell you anything about code paths which you exercise with it in place. Using it on the opening example: -```bash -% scalac -Xcheckinit a.scala -% scala -e 'new C' -scala.UninitializedFieldError: Uninitialized field: a.scala: 13 - at C.x2(a.scala:13) - at A.(a.scala:5) - at B.(a.scala:7) - at C.(a.scala:12) -``` + + % scalac -Xcheckinit a.scala + % scala -e 'new C' + scala.UninitializedFieldError: Uninitialized field: a.scala: 13 + at C.x2(a.scala:13) + at A.(a.scala:5) + at B.(a.scala:7) + at C.(a.scala:12) ### Solutions ### @@ -72,28 +69,26 @@ Approaches for avoiding null values include: #### Use lazy vals #### -```scala -abstract class A { - val x1: String - lazy val x2: String = "mom" - - println("A: " + x1 + ", " + x2) -} -class B extends A { - lazy val x1: String = "hello" - - println("B: " + x1 + ", " + x2) -} -class C extends B { - override lazy val x2: String = "dad" - - println("C: " + x1 + ", " + x2) -} -// scala> new C -// A: hello, dad -// B: hello, dad -// C: hello, dad -``` + abstract class A { + val x1: String + lazy val x2: String = "mom" + + println("A: " + x1 + ", " + x2) + } + class B extends A { + lazy val x1: String = "hello" + + println("B: " + x1 + ", " + x2) + } + class C extends B { + override lazy val x2: String = "dad" + + println("C: " + x1 + ", " + x2) + } + // scala> new C + // A: hello, dad + // B: hello, dad + // C: hello, dad Usually the best answer. Unfortunately you cannot declare an abstract lazy val. If that is what you're after, your options include: @@ -106,66 +101,63 @@ An exception during initialization of a lazy val will cause the right hand side Note that using multiple lazy vals creates a new risk: cycles among lazy vals can result in a stack overflow on first access. #### Use early definitions #### -```scala -abstract class A { - val x1: String - val x2: String = "mom" - - println("A: " + x1 + ", " + x2) -} -class B extends { - val x1: String = "hello" -} with A { - println("B: " + x1 + ", " + x2) -} -class C extends { - override val x2: String = "dad" -} with B { - println("C: " + x1 + ", " + x2) -} -// scala> new C -// A: hello, dad -// B: hello, dad -// C: hello, dad -``` + abstract class A { + val x1: String + val x2: String = "mom" + + println("A: " + x1 + ", " + x2) + } + class B extends { + val x1: String = "hello" + } with A { + println("B: " + x1 + ", " + x2) + } + class C extends { + override val x2: String = "dad" + } with B { + println("C: " + x1 + ", " + x2) + } + // scala> new C + // A: hello, dad + // B: hello, dad + // C: hello, dad Early definitions are a bit unwieldy, there are limitations as to what can appear and what can be referenced in an early definitions block, and they don't compose as well as lazy vals: but if a lazy val is undesirable, they present another option. They are specified in SLS 5.1.6. #### Use constant value definitions #### -```scala -abstract class A { - val x1: String - val x2: String = "mom" - - println("A: " + x1 + ", " + x2) -} -class B extends A { - val x1: String = "hello" - final val x3 = "goodbye" - - println("B: " + x1 + ", " + x2) -} -class C extends B { - override val x2: String = "dad" - - println("C: " + x1 + ", " + x2) -} -abstract class D { - val c: C - val x3 = c.x3 // no exceptions! - println("D: " + c + " but " + x3) -} -class E extends D { - val c = new C - println(s"E: ${c.x1}, ${c.x2}, and $x3...") -} -//scala> new E -//D: null but goodbye -//A: null, null -//B: hello, null -//C: hello, dad -//E: hello, dad, and goodbye... -``` + abstract class A { + val x1: String + val x2: String = "mom" + + println("A: " + x1 + ", " + x2) + } + class B extends A { + val x1: String = "hello" + final val x3 = "goodbye" + + println("B: " + x1 + ", " + x2) + } + class C extends B { + override val x2: String = "dad" + + println("C: " + x1 + ", " + x2) + } + abstract class D { + val c: C + val x3 = c.x3 // no exceptions! + println("D: " + c + " but " + x3) + } + class E extends D { + val c = new C + println(s"E: ${c.x1}, ${c.x2}, and $x3...") + } + //scala> new E + //D: null but goodbye + //A: null, null + //B: hello, null + //C: hello, dad + //E: hello, dad, and goodbye... + Sometimes all you need from an interface is a compile-time constant. Constant values are stricter than strict and earlier than early definitions and have even more limitations,