the bellow code :
scala> class A {
| def hi = "Hello from A"
| override def toString = getClass.getName
| }
defined class A
scala> val a = new A()
a: A = A
scala> a.toString
res10: String = A
scala> println(s"${a.toString}")
$line31.$read$$iw$$iw$A
It is printing ok when using a.toString expression, not when using println(s"${a.toString}"). The problem is getClass.getName. In other cases it works nice.
Thanks in advance for any help
REPL filters its output to hide template wrappings.
$ scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_92).
Type in expressions for evaluation. Or try :help.
scala> class A
defined class A
scala> val a = new A
a: A = A#4926097b
scala> a.getClass
res0: Class[_ <: A] = class A
scala> $intp.isettings.
allSettings deprecation deprecation_= maxAutoprintCompletion maxPrintString toString unwrapStrings
scala> $intp.isettings.unwrapStrings = false
$intp.isettings.unwrapStrings: Boolean = false
scala> a.getClass
res1: Class[_ <: A] = class $line3.$read$$iw$$iw$A
You can also compare output clipping:
scala> (1 to 1000).mkString
res2: String = 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629...
scala> println((1 to 1000).mkString)
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
Scroll right to see the ellipsis on the first line.
Since names of classes inside REPL are different, REPL needs to convert internal names back. It does it well enough when displaying strings, but fails when string is passed to an external method, e.g. println or toList:
scala> a.toString
res1: String = A
scala> a.toString.toList
res2: List[Char] = List($, l, i, n, e, 4, ., $, r, e, a, d, $, $, i, w, $, $, i, w, $, A)
scala> "$line4.$read$$iw$$iw$A"
res3: String = A
Run the scala repl using: scala -Xprint:parser
Then run the successive commands. The output $line3.$read$$iw$$iw$A represents the path to the A object. $line is a package, $read and $iw are objects under which the object A is nested.
For the case of println(s"${a.toString}")
scala> println(s"${a.toString}")
[[syntax trees at end of parser]] // <console>
package $line5 {
object $read extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
import $line3.$read.$iw.$iw.A;
import $line4.$read.$iw.$iw.a;
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
val res0 = println(StringContext("", "").s(a.toString))
}
}
}
}
[[syntax trees at end of parser]] // <console>
package $line5 {
object $eval extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
lazy val $result = $line5.$read.$iw.$iw.res0;
lazy val $print: String = {
$line5.$read.$iw.$iw;
"" <-- // SOMETHING OFF HERE! NO OUTPUT STRING BEING GENERATED?
}
}
}
$line3.$read$$iw$$iw$A
Now for the case of a.toString:
scala> a.toString
[[syntax trees at end of parser]] // <console>
package $line6 {
object $read extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
import $line3.$read.$iw.$iw.A;
import $line4.$read.$iw.$iw.a;
object $iw extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
val res1 = a.toString
}
}
}
}
[[syntax trees at end of parser]] // <console>
package $line6 {
object $eval extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
lazy val $result = $line6.$read.$iw.$iw.res1;
lazy val $print: String = {
$line6.$read.$iw.$iw; // *CORRECTLY GENERATES THE RESULT STRING.*
"".$plus("res1: String = ").$plus(scala.runtime.ScalaRunTime.replStringOf($line6.$read.$iw.$iw.res1, 1000))
}
}
}
res1: String = A
It is the way REPL is compiling A. In a simple app like below there are no issues
Each line in the REPL is wrapped into it's own package.. and that auto generated package name is what you see prepended to class name A.
object ScalaApp extends App {
class A {
def hi = "Hello from A"
override def toString = getClass.getName
}
val a = new A()
println(a.toString)
println(s"${a.toString}")
}
Related
As far as i understand, #specialized annotation should generate some unboxed code for every primitive type i mentioned, but this doesn't work:
scala> def aaa[#specialized(Int, Double, Float, Long) T] = (5.0).doubleValue.asInstanceOf[T]
aaa: [T]=> T
scala> aaa[Int]
unrecoverable error (inside interpreter/compiler)
This compiles:
scala> def aaa[#specialized(Int, Double, Float, Long) T](a: T) = (5.0).doubleValue.asInstanceOf[T]
aaa: [T]=> T
scala> aaa[Int](0)
ClassCastException
But it still uses boxed type for asInstanceOf[T]. This obviously works:
scala> (5.0).asInstanceOf[Int]
res28: Int = 5
UPDATE:
Type erasure and answers like that Writing a generic cast function Scala has nothing to do with my problem. Type erasure just preventing compiler from adding typecast byte-code operation for generics, but eventually it will be added - see ClassCastException (generated by this op) in my REPL
The problem was in Scala REPL - #specialized doesn't work there. Compiling def aaa[#specialized(Int) T] = (5.0).asInstanceOf[T] with scalac gives:
public <T> T aaa();
Code:
0: ldc2_w #15 // double 5.0d
3: invokestatic #22 // Method scala/runtime/BoxesRunTime
.boxToDouble:(D)Ljava/lang/Double;
6: areturn
public int aaa$mIc$sp();
Code:
0: ldc2_w #15 // double 5.0d
3: d2i
4: ireturn
d2i is exactly what i was expecting. And of course everything works fine with scalac (so I don't need pattern matching for every possible type). So it's just the issue with interpreter.
The method is specialized, but under separate compilation (i.e., different lines), the specialized method isn't invoked.
In the following, b.B.f works, c.B.f is broken.
$ scala -Xprint:typer,cleanup
scala> :pa -raw
// Entering paste mode (ctrl-D to finish)
package a { object A { def aaa[#specialized(Int) T] = (5.0).doubleValue.asInstanceOf[T] }}
package b { object B { def f = a.A.aaa[Int] }}
// Exiting paste mode, now interpreting.
[[syntax trees at end of typer]] // <pastie>
package <empty> {
package a {
object A extends scala.AnyRef {
def <init>(): a.A.type = {
A.super.<init>();
()
};
def aaa[#specialized(scala.Int) T]: T = scala.this.Predef.double2Double(5.0).doubleValue().asInstanceOf[T]
}
};
package b {
object B extends scala.AnyRef {
def <init>(): b.B.type = {
B.super.<init>();
()
};
def f: Int = a.A.aaa[Int]
}
}
}
[[syntax trees at end of cleanup]] // <pastie>
package <empty> {
package a {
object A extends Object {
def aaa(): Object = scala.Double.box(scala.this.Predef.double2Double(5.0).doubleValue());
<specialized> def aaa$mIc$sp(): Int = scala.this.Predef.double2Double(5.0).doubleValue().toInt();
def <init>(): a.A.type = {
A.super.<init>();
()
}
}
};
package b {
object B extends Object {
def f(): Int = a.A.aaa$mIc$sp();
def <init>(): b.B.type = {
B.super.<init>();
()
}
}
}
}
scala> :pa -raw
// Entering paste mode (ctrl-D to finish)
package c { object B { def f = a.A.aaa[Int] }}
// Exiting paste mode, now interpreting.
[[syntax trees at end of typer]] // <pastie>
package c {
object B extends scala.AnyRef {
def <init>(): c.B.type = {
B.super.<init>();
()
};
def f: Int = a.A.aaa[Int]
}
}
[[syntax trees at end of cleanup]] // <pastie>
package c {
object B extends Object {
def f(): Int = scala.Int.unbox(a.A.aaa());
def <init>(): c.B.type = {
B.super.<init>();
()
}
}
}
Perhaps you just need a more recent compiler? here's what I get with 2.11.2:
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_72).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def aaa[#specialized(Int, Double, Float, Long) T] = (5.0).doubleValue.asInstanceOf[T]
aaa: [T]=> T
scala> aaa[Int]
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:105)
... 33 elided
scala> aaa[Float]
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Float
at scala.runtime.BoxesRunTime.unboxToFloat(BoxesRunTime.java:113)
... 33 elided
scala> aaa[Double]
res2: Double = 5.0
scala> 5.0.asInstanceOf[Int]
res3: Int = 5
scala> 5.0.asInstanceOf[Integer]
java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
... 33 elided
Note that you can directly do 5.0.asInstanceOf[Int] but not 5.0.asInstanceOf[Integer]. Also note that the ClassCastException that you get with aaa[Int] is referring to java.lang.Integer not Scala's Int class. I suspect what goes on here is that the #specialized annotation is generating a function, aaa, that has an "Int" specialization but because of type erasure and boxing is converting that to java.lang.Integer and there is no automatic conversion with asInstanceOf between Double and Integer.
Considering this simple example:
trait A { def a: String = "a"; def a2: String }
case class C(b: String, c: String) extends A {
val a2 = "a2"
}
val c = C("b", "")
val copy = c.copy(c="c")
When I update field c with .copy(c="c"), are other fields(a,a2 and b) copied? Event though only their references are copied, if I have a huge hierarchy tree, will .copy become very costly?
Similarly:
class Foo {
val list = List(1,2,3,4,5,6)
}
val foo1 = new Foo
val foo2 = new Foo
Do foo1 and foo2 share an instance of List, or every time I instantiate a Foo it creates a new List? What if list is a var instead of val?
Generally Scala is immutable, you usually have to handle mutable cases yourself. Also case classes are immutable by nature and their copy method is generated by the compiler. So yes, they would share the same object reference. This is one of the reasons immutability is nice.
Your second question is a bit different. In that case the classes are constructed one after the other in seperate contexts.
It's also a good idea to check what's being compiled:
>scalac -print test.scala
[[syntax trees at end of cleanup]] // test.scala
package test {
class Foo extends Object {
private[this] val list: List = _;
<stable> <accessor> def list(): List = Foo.this.list;
def <init>(): b.Foo = {
Foo.super.<init>();
Foo.this.list = immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1, 2, 3, 4, 5, 6}));
()
}
}
}
From this we can see Scala creating a new list each time. Changing this to var won't change anything, we can check:
>scalac -print test.scala
[[syntax trees at end of cleanup]] // test.scala
package test {
class Foo extends Object {
private[this] var list: List = _;
<accessor> def list(): List = Foo.this.list;
<accessor> def list_=(x$1: List): Unit = Foo.this.list = x$1;
def <init>(): b.Foo = {
Foo.super.<init>();
Foo.this.list = immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1, 2, 3, 4, 5, 6}));
()
}
}
}
It only generated a setter method for it (def list_=(x$1: List)).
If you would like to reference the same list in both cases then initialize it with an object's default list:
object Foo {
val DefaultList = List(1,2,3,4,5,6)
}
class Foo {
var list = Foo.DefaultList
}
Which compiles to the following:
>scalac -print test.scala
[[syntax trees at end of cleanup]] // test.scala
package test {
object Foo extends Object {
private[this] val DefaultList: List = _;
<stable> <accessor> def DefaultList(): List = Foo.this.DefaultList;
def <init>(): test.Foo.type = {
Foo.super.<init>();
Foo.this.DefaultList = immutable.this.List.apply(scala.this.Predef.wrapIntArray(Array[Int]{1, 2, 3, 4, 5, 6}));
()
}
};
class Foo extends Object {
private[this] var list: List = _;
<accessor> def list(): List = Foo.this.list;
<accessor> def list_=(x$1: List): Unit = Foo.this.list = x$1;
def <init>(): test.Foo = {
Foo.super.<init>();
Foo.this.list = Foo.DefaultList();
()
}
}
}
As you can see the list is only created once and then the reference through the def DefaultList(): List assigned on each Foo class instantiation.
To answer my own first question:
The concrete vals in a trait are implemented as a Java static method:
// scala
trait A { def a: String = "a"; }
// java
public static java.lang.String a(A);
Code:
0: ldc #8 // String a
2: areturn
Of course, a static method can't be copied. So I don't need to worry about huge hierarchy tree.
The abstract val is implemented as a hard-coded constant:
// scala
trait B { def b: String }
case class C() { def b = "b" }
// java
public java.lang.String b();
Code:
0: ldc #47 // String b
2: areturn
It's fine as well.
The only thing(s) will be copied when I call .copy() are the fields in constructor parameter list.
I am trying to understand how scoping works in the REPL. I tried following Section 5.1.1 of Joshua Suereth's book Scala in depth.This is on Windows XP, Java 7 and Scala 2.9.1. I declare a class Dinner in the REPL. The binding Dinner exists in the local scope. Then I instantiate because it is locally bound.
scala> class Dinner {
| val veggie="broccoli"
| def announceDinner(veggie: String){
| println("Dinner happens to be tasteless " + veggie + " soup")
| }
| }
defined class Dinner
scala> new Dinner
res1: Dinner = Dinner#27fb77
So far so good. The name Dinner was bound locally and we could also construct a val x that could hold a reference to new Dinner.
From what I know so far, The REPL will wrap the above code in objects internally. Okay, my knowledge of Scala is not quite as deep yet and I am trying to understand how Class might be internally wrapped by the REPL.
Is there an REPL command that can help me evaluate these objects?
Here goes a very quick and dirty way to what is going on in the REPL.
Invoke the REPL with scala -Xprint:typer
scala> class Dinner {
| val veggie="broccoli"
| def announceDinner(veggie: String){
| println("Dinner happens to be tasteless " + veggie + " soup")
| }
| }
[[syntax trees at end of typer]]// Scala source: <console>
package $line1 {
final object $read extends java.lang.Object with ScalaObject {
def this(): object $line1.$read = {
$read.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line1.$read.$iw = {
$iw.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line1.$read.$iw.$iw = {
$iw.super.this();
()
};
class Dinner extends java.lang.Object with ScalaObject {
def this(): $line1.$read.$iw.$iw.Dinner = {
Dinner.super.this();
()
};
private[this] val veggie: java.lang.String = "broccoli";
<stable> <accessor> def veggie: java.lang.String = Dinner.this.veggie;
def announceDinner(veggie: String): Unit = scala.this.Predef.println("Dinner happens to be tasteless ".+(veggie).+(" soup"))
}
}
}
}
}
[[syntax trees at end of typer]]// Scala source: <console>
package $line1 {
final object $eval extends java.lang.Object with ScalaObject {
def this(): object $line1.$eval = {
$eval.super.this();
()
};
private[this] val $print: String = {
$read.$iw.$iw;
"defined class Dinner\012"
};
<stable> <accessor> def $print: String = $eval.this.$print
}
}
defined class Dinner
As you can check above Dinner ends up wrapped into $line1.$read.$iw.$iw. Now let's see what happens next:
[[syntax trees at end of typer]]// Scala source: <console>
package $line2 {
final object $read extends java.lang.Object with ScalaObject {
def this(): object $line2.$read = {
$read.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line2.$read.$iw = {
$iw.super.this();
()
};
import $line1.$read.$iw.$iw.Dinner;
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line2.$read.$iw.$iw = {
$iw.super.this();
()
};
private[this] val res0: $line1.$read.$iw.$iw.Dinner = new $line1.$read.$iw.$iw.Dinner();
<stable> <accessor> def res0: $line1.$read.$iw.$iw.Dinner = $iw.this.res0
}
}
}
}
[[syntax trees at end of typer]]// Scala source: <console>
package $line2 {
final object $eval extends java.lang.Object with ScalaObject {
def this(): object $line2.$eval = {
$eval.super.this();
()
};
lazy private[this] var $result: $line1.$read.$iw.$iw.Dinner = {
$eval.this.$print;
$line2.$read.$iw.$iw.res0
};
private[this] val $print: String = {
$read.$iw.$iw;
"res0: $line1.$read.$iw.$iw.Dinner = ".+(scala.runtime.ScalaRunTime.replStringOf($line2.$read.$iw.$iw.res0, 1000))
};
<stable> <accessor> def $print: String = $eval.this.$print
}
}
Basically the same thing as before but using $line2 instead of $line1. Notice the import $line1.$read.$iw.$iw.Dinner right before $line2.$read.$iw.$iw.
This way we can see why defining companion objects in two different lines doesn't work, they end up wrapped into different objects and companions need to be defined in the same scope/source file.
Scala 2.8.2 has a Seq.apply method, so that you can write the following in the REPL:
val l = Seq(1, 2)
l: Seq[In] = List(1, 2)
This still works in Scala 2.9.2, but what puzzles me is that according to the documentation, there is no such thing as a scala.collection.Seq.apply method anymore.
I checked with scala -Xprint:typer and this is what it prints:
[[syntax trees at end of typer]]// Scala source: <console>
package $line14 {
final object $read extends java.lang.Object with ScalaObject {
def this(): object $line14.$read = {
$read.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line14.$read.$iw = {
$iw.super.this();
()
};
final object $iw extends java.lang.Object with ScalaObject {
def this(): object $line14.$read.$iw.$iw = {
$iw.super.this();
()
};
private[this] val l: Seq[Int] = collection.this.Seq.apply[Int](1, 2);
<stable> <accessor> def l: Seq[Int] = $iw.this.l
}
}
}
}
[[syntax trees at end of typer]]// Scala source: <console>
package $line14 {
final object $eval extends java.lang.Object with ScalaObject {
def this(): object $line14.$eval = {
$eval.super.this();
()
};
lazy private[this] var $result: Seq[Int] = {
$eval.this.$print;
$line14.$read.$iw.$iw.l
};
private[this] val $print: String = {
$read.$iw.$iw;
"l: Seq[Int] = ".+(scala.runtime.ScalaRunTime.replStringOf($line14.$read.$iw.$iw.l, 1000))
};
<stable> <accessor> def $print: String = $eval.this.$print
}
}
l: Seq[Int] = List(1, 2)
So the result is effectively:
collection.this.Seq.apply[Int](1, 2)
which indicates that it still calls Seq.apply, but where is this method?
It's really a bug in Scaladoc 2.9.2.
I've inspected the scala-library.jar and found that the companion object scala.collection.Seq indirectly extends scala.collection.generic.GenericCompanion[Seq], which effectively provides the method signature:
def apply[A](elems: A*): Seq[A]
This in turn calls newBuilder, which is overridden in Seq to return:
scala.collection.immutable.Seq.newBuilder[A]
I've seen the args.foreach(arg => println(arg)), but when I search the doc http://www.scala-lang.org/api/current/index.html#scala.Array . I don't find it there and its companion object doc.
Any advice?
Thanks
Array gets operations such as foreach from scala.collection.mutable.ArrayOps - so you can lookup ArrayOps in the documentation to see what methods are available on arrays.
Predef contains a number of implicit conversion methods to make these available for arrays.
Unfortunately you can't see in the Scala API documentation for Array that these methods are available via the implicits in Predef.
As Jesper said, it's not really easy to find documentation on methods acquired via implicit conversions.
The ones defined for Array and the rationale behind them are explained here.
One (not particularly handy...) general way of finding out where a particular method comes from (in cases like yours, where it comes from an implicit conversion) is to use the -print option of the scala REPL.
If you run scala -print you will get:
scala> Array(1,2,3,4)
// ..... omitted for brevity
res0: Array[Int] = Array(1, 2, 3, 4)
scala> res0 foreach (println)
[[syntax trees at end of cleanup]]// Scala source: <console>
package $line2 {
final object $read extends java.lang.Object with ScalaObject {
def this(): object $line2.$read = {
$read.super.this();
()
}
};
#SerialVersionUID(0) final <synthetic> class $read$$iw$$iw$$anonfun$1 extends
scala.runtime.AbstractFunction1 with Serializable {
final def apply(x: java.lang.Object): Unit = scala.this.Predef.println(x);
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = {
$read$$iw$$iw$$anonfun$1.this.apply(v1);
scala.runtime.BoxedUnit.UNIT
};
def this(): anonymous class $read$$iw$$iw$$anonfun$1 = {
$read$$iw$$iw$$anonfun$1.super.this();
()
}
};
final object $read$$iw$$iw extends java.lang.Object with ScalaObject {
private[this] val res1: scala.runtime.BoxedUnit = _;
<stable> <accessor> def res1(): Unit = ();
def this(): object $line2.$read$$iw$$iw = {
$read$$iw$$iw.super.this();
$read$$iw$$iw.this.res1 = {
scala.this.Predef.intArrayOps($line1.$read$$iw$$iw.res0()).foreach({
{
(new anonymous class $read$$iw$$iw$$anonfun$1(): Function1)
}
});
scala.runtime.BoxedUnit.UNIT
};
()
}
};
final object $read$$iw extends java.lang.Object with ScalaObject {
def this(): object $line2.$read$$iw = {
$read$$iw.super.this();
()
}
}
}
[[syntax trees at end of cleanup]]// Scala source: <console>
package $line2 {
final object $eval extends java.lang.Object with ScalaObject {
#volatile protected var bitmap$0: Int = 0;
<stable> <accessor> lazy def $result(): Unit = {
if ($eval.this.bitmap$0.&(1).==(0))
{
$eval.this.synchronized({
if ($eval.this.bitmap$0.&(1).==(0))
{
{
$eval.this.$print();
$line2.$read$$iw$$iw.res1()
};
$eval.this.bitmap$0 = $eval.this.bitmap$0.|(1);
()
};
scala.runtime.BoxedUnit.UNIT
});
()
};
()
};
private[this] val $print: java.lang.String = _;
<stable> <accessor> def $print(): java.lang.String = $eval.this.$print;
def this(): object $line2.$eval = {
$eval.super.this();
$eval.this.$print = {
$line2.$read$$iw$$iw;
""
};
()
}
}
}
1
2
3
4
If you look for .foreach inside this code, you will find the relevant line, that tells you the method is actually called on intArrayOps:
scala.this.Predef.intArrayOps($line1.$read$$iw$$iw.res0()).foreach(