Can someone explain me in detail about orders in which constructors are called in inheritance in scala please? Say I have:
abstract class A {
private var data: T = compute()
protected def compute(): T
}
class ImpA extends A {
var a = 0
override def compute() {
a = 1
null.asInstanceOf[T] // doesn't matter
}
}
val inst = new ImpA
Then it appears that inst.a == 0, so I guess that what happens is that when ImpA's constructor is called then, A constructor is called also, which actually triggers compute() that should set a = 1. But then scala goes back down to ImpA's constructor and reset a = 0. Is that it?
Is there some well-known pattern to avoid this properly? (I'm not really trying to fix this problem that can be easily dealt with, though if there are patterns that are advised I'm eager to know them; but I'd rather like to have a deep understanding of what's happening, and hopefully know why reinitializing the variable a could be interested in that case. And also what would happen internally if it was a val as it would lead to assign several references to the same variables if the logic is kept...).
Thanks in advance.
EDIT: something fun also is when you just change ImpA.a and use a reference instead of a var:
class ImpA extends A {
class B {
var b = 0
}
val b = new B
override def compute() {
b.b += 1
null.asInstanceOf[T] // doesn't matter
}
}
then it throws a java.lang.NullPointerException because b isn't instantiated yet. Following Yuval Itzchakov solution, here's what it compiles into:
abstract class A extends Object {
private[this] var data: Object = _;
<accessor> private def data(): Object = A.this.data;
<accessor> private def data_=(x$1: Object): Unit = A.this.data = x$1;
protected def compute(): Object;
def <init>(): test.A = {
A.super.<init>();
A.this.data = A.this.compute();
()
}
};
class ImpA extends test.A {
private[this] val b: test.ImpA$B = _;
<stable> <accessor> def b(): test.ImpA$B = ImpA.this.b;
override def compute(): Unit = {
ImpA.this.b().b_=(ImpA.this.b().b().+(1));
{
(null: Object);
()
}
};
override <bridge> <artifact> def compute(): Object = {
ImpA.this.compute();
scala.runtime.BoxedUnit.UNIT
};
def <init>(): test.ImpA = {
ImpA.super.<init>();
ImpA.this.b = new test.ImpA$B(ImpA.this);
()
}
};
class ImpA$B extends Object {
private[this] var b: Int = _;
<accessor> def b(): Int = ImpA$B.this.b;
<accessor> def b_=(x$1: Int): Unit = ImpA$B.this.b = x$1;
<synthetic> <paramaccessor> <artifact> protected val $outer: test.ImpA = _;
<synthetic> <stable> <artifact> def $outer(): test.ImpA = ImpA$B.this.$outer;
def <init>($outer: test.ImpA): test.ImpA$B = {
if ($outer.eq(null))
throw null
else
ImpA$B.this.$outer = $outer;
ImpA$B.super.<init>();
ImpA$B.this.b = 0;
()
}
}
Though it's a bit harder to understand properly, it explains quite straightforwardly why the NullPointerException is thrown.
But if you use this time a lazy val b = new B, then it works:
class ImpA extends test.A {
#volatile private[this] var bitmap$0: Boolean = false;
private def b$lzycompute(): test.ImpA$B = {
{
ImpA.this.synchronized({
if (ImpA.this.bitmap$0.unary_!())
{
ImpA.this.b = new test.ImpA$B(ImpA.this);
ImpA.this.bitmap$0 = true;
()
};
scala.runtime.BoxedUnit.UNIT
});
()
};
ImpA.this.b
};
lazy private[this] var b: test.ImpA$B = _;
<stable> <accessor> lazy def b(): test.ImpA$B = if (ImpA.this.bitmap$0.unary_!())
ImpA.this.b$lzycompute()
else
ImpA.this.b;
override def compute(): Unit = {
ImpA.this.b().b_=(ImpA.this.b().b().+(1));
{
(null: Object);
()
}
};
override <bridge> <artifact> def compute(): Object = {
ImpA.this.compute();
scala.runtime.BoxedUnit.UNIT
};
def <init>(): test.ImpA = {
ImpA.super.<init>();
()
}
};
Let's see what the compiler generates when compiling (using the -Xprint:jvm flag):
class ImpA extends com.testing.A {
private[this] var a: Int = _;
<accessor> def a(): Int = ImpA.this.a;
<accessor> def a_=(x$1: Int): Unit = ImpA.this.a = x$1;
override def compute(): String = {
ImpA.this.a_=(1);
(null: String)
};
override <bridge> <artifact> def compute(): Object = ImpA.this.compute();
def <init>(): com.testing.ImpA = {
ImpA.super.<init>();
ImpA.this.a = 0;
()
}
};
What do we see? We see that the constructor running for ImplA (defined as the <init> method) first calls ImpA.super.<init>(), which is a call to A to initialize itself first. As initialization code looks like this:
def <init>(): com.testing.A = {
A.super.<init>();
A.this.data = A.this.compute();
()
}
It calls A.super, which is Object, and then calls A.this.compute(). This method initializes a to hold the value 1. Once that initialization finishes, ImplA sets a to 0, as you told it to do during constructor initialization. That is why you're seeing the value 0 for a.
To sum up, the execution flow is as follows:
ImplA calls As init method
A calls compute, which is invoked on ImplA
ImplA.compute assigns a the value 1
ImplA assigns a the value 0
For more, see http://docs.scala-lang.org/tutorials/FAQ/initialization-order.html
Related
I have an array of Any (in real life, it's a Spark Row, but it's sufficient to isolate the problem)
object Row {
val buffer : Array[Any] = Array(42, 21, true)
}
And I want to apply some operations on its elements.
So, I've defined a simple ADT to define a compute operation on a type A
trait Op[A] {
def cast(a: Any) : A = a.asInstanceOf[A]
def compute(a: A) : A
}
case object Count extends Op[Int] {
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op[Boolean] {
override def compute(a: Boolean): Boolean = a
}
Given that I have a list of all operations and I know which operation is to apply to each element, let's use these operations.
object GenericsOp {
import Row._
val ops = Seq(Count, Exist)
def compute() = {
buffer(0) = ops(0).compute(ops(0).cast(buffer(0)))
buffer(1) = ops(0).compute(ops(0).cast(buffer(1)))
buffer(2) = ops(1).compute(ops(1).cast(buffer(2)))
}
}
By design, for a given op, types are aligned between cast and combine. But unfortunately the following code does not compile. The error is
Type mismatch, expected: _$1, actual: AnyVal
Is there a way to make it work ?
I've found a workaround by using abstract type member instead of type parameter.
object AbstractOp extends App {
import Row._
trait Op {
type A
def compute(a: A) : A
}
case object Count extends Op {
type A = Int
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op {
type A = Boolean
override def compute(a: Boolean): Boolean = a
}
val ops = Seq(Count, Exist)
def compute() = {
val op0 = ops(0)
val op1 = ops(1)
buffer(0) = ops(0).compute(buffer(0).asInstanceOf[op0.A])
buffer(1) = ops(0).compute(buffer(1).asInstanceOf[op0.A])
buffer(2) = ops(1).compute(buffer(2).asInstanceOf[op1.A])
}
}
Is there a better way ?
It seems that your code can be simplified by making Op[A] extend Any => A:
trait Op[A] extends (Any => A) {
def cast(a: Any) : A = a.asInstanceOf[A]
def compute(a: A) : A
def apply(a: Any): A = compute(cast(a))
}
case object Count extends Op[Int] {
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op[Boolean] {
override def compute(a: Boolean): Boolean = a
}
object AbstractOp {
val buffer: Array[Any] = Array(42, 21, true)
val ops: Array[Op[_]] = Array(Count, Count, Exist)
def main(args: Array[String]): Unit = {
for (i <- 0 until buffer.size) {
buffer(i) = ops(i)(buffer(i))
}
println(buffer.mkString("[", ",", "]"))
}
}
Since it's asInstanceOf everywhere anyway, it does not make the code any less safe than what you had previously.
Update
If you cannot change the Op interface, then invoking cast and compute is a bit more cumbersome, but still possible:
trait Op[A] {
def cast(a: Any) : A = a.asInstanceOf[A]
def compute(a: A) : A
}
case object Count extends Op[Int] {
override def compute(a: Int): Int = a + 1
}
case object Exist extends Op[Boolean] {
override def compute(a: Boolean): Boolean = a
}
object AbstractOp {
val buffer: Array[Any] = Array(42, 21, true)
val ops: Array[Op[_]] = Array(Count, Count, Exist)
def main(args: Array[String]): Unit = {
for (i <- 0 until buffer.size) {
buffer(i) = ops(i) match {
case op: Op[t] => op.compute(op.cast(buffer(i)))
}
}
println(buffer.mkString("[", ",", "]"))
}
}
Note the ops(i) match { case op: Opt[t] => ... } part with a type-parameter in the pattern: this allows us to make sure that cast returns a t that is accepted by compute.
As a more general solution than Andrey Tyukin's, you can define the method outside Op, so it works even if Op can't be modified:
def apply[A](op: Op[A], x: Any) = op.compute(op.cast(x))
buffer(0) = apply(ops(0), buffer(0))
Say I have this situation
class Pipe {
var vel = 3.4
var V = 300
var a = 10.2
var in = ???
var TotV = V+in
var out = TotV*a/vel
}
val pipe1 = new Pipe
val pipe2 = new Pipe
The in variable is were my problem is, what i'd like to do is get the out variable from pipe1 and feed that in as the in variable for pipe 2 effectively to join the two pipes but I cant figure out if this is even possible in the same class. So I can do it manually but need to know if its possible to do in the class.
pipe2.in = pipe1.out
my attempted fix was to add an ID field then try and use that to reference an instance with a higher id field but that doesnt seem doable. ie
class Pipe(id:Int) {
var vel = 3.4
var V = 300
var a = 10.2
var in = Pipe(id+1).out //this is the sticking point, I want to reference instances of this class and use their out value as in value for instances with a lower ID
var TotV = V+in
var out = TotV*a/vel
}
any help would be appreciated
You can do this by defining a companion object for the class and passing in the upstream pipe as an optional parameter to the factory method, then extracting its in value and passing it to the class constructor, as follows:
object Pipe {
def apply(upstreamPipe: Option[Pipe]): Pipe = {
val inValue = upstreamPipe match {
case Some(pipe) => pipe.out
case None => 0 // or whatever your default value is
new Pipe(inValue)
}
You would then call
val pipe1 = Pipe(None)
val pipe2 = Pipe(Some(pipe1))
Unfortunately your question is not clear now. Under certain assumptions what you describe looks like what is now called "FRP" aka "Functional Reactive Programming". If you want to do it in a serious way, you probably should take a look at some mature library such as RxScala or Monix that handle many important in the real world details such as error handling or scheduling/threading and many others.
For a simple task you might roll out a simple custom implementation like this:
trait Observable {
def subscribe(subscriber: Subscriber): RxConnection
}
trait RxConnection {
def disconnect(): Unit
}
trait Subscriber {
def onChanged(): Unit
}
trait RxOut[T] extends Observable {
def currentValue: Option[T]
}
class MulticastObservable extends Observable with Subscriber {
private val subscribers: mutable.Set[Subscriber] = mutable.HashSet()
override def onChanged(): Unit = subscribers.foreach(s => s.onChanged())
override def subscribe(subscriber: Subscriber): RxConnection = {
subscribers.add(subscriber)
new RxConnection {
override def disconnect(): Unit = subscribers.remove(subscriber)
}
}
}
abstract class BaseRxOut[T](private var _lastValue: Option[T]) extends RxOut[T] {
private val multicast = new MulticastObservable()
protected def lastValue: Option[T] = _lastValue
protected def lastValue_=(value: Option[T]): Unit = {
_lastValue = value
multicast.onChanged()
}
override def currentValue: Option[T] = lastValue
override def subscribe(subscriber: Subscriber): RxConnection = multicast.subscribe(subscriber)
}
class RxValue[T](initValue: T) extends BaseRxOut[T](Some(initValue)) {
def value: T = this.lastValue.get
def value_=(value: T): Unit = {
this.lastValue = Some(value)
}
}
trait InputConnector[T] {
def connectInput(input: RxOut[T]): RxConnection
}
class InputConnectorImpl[T] extends BaseRxOut[T](None) with InputConnector[T] {
val inputHolder = new RxValue[Option[(RxOut[T], RxConnection)]](None)
private def updateValue(): Unit = {
lastValue = for {inputWithDisconnect <- inputHolder.value
value <- inputWithDisconnect._1.currentValue}
yield value
}
override def connectInput(input: RxOut[T]): RxConnection = {
val current = inputHolder.value
if (current.exists(iwd => iwd._1 == input))
current.get._2
else {
current.foreach(iwd => iwd._2.disconnect())
inputHolder.value = Some(input, input.subscribe(() => this.updateValue()))
updateValue()
new RxConnection {
override def disconnect(): Unit = {
if (inputHolder.value.exists(iwd => iwd._1 == input)) {
inputHolder.value.foreach(iwd => iwd._2.disconnect())
inputHolder.value = None
updateValue()
}
}
}
}
}
}
abstract class BaseRxCalculation[Out] extends BaseRxOut[Out](None) {
protected def registerConnectors(connectors: InputConnectorImpl[_]*): Unit = {
connectors.foreach(c => c.subscribe(() => this.recalculate()))
}
private def recalculate(): Unit = {
var newValue = calculateOutput()
if (newValue != lastValue) {
lastValue = newValue
}
}
protected def calculateOutput(): Option[Out]
}
case class RxCalculation1[In1, Out](func: Function1[In1, Out]) extends BaseRxCalculation[Out] {
private val conn1Impl = new InputConnectorImpl[In1]
def conn1: InputConnector[In1] = conn1Impl // show to the outer world only InputConnector
registerConnectors(conn1Impl)
override protected def calculateOutput(): Option[Out] = {
for {v1 <- conn1Impl.currentValue}
yield func(v1)
}
}
case class RxCalculation2[In1, In2, Out](func: Function2[In1, In2, Out]) extends BaseRxCalculation[Out] {
private val conn1Impl = new InputConnectorImpl[In1]
def conn1: InputConnector[In1] = conn1Impl // show to the outer world only InputConnector
private val conn2Impl = new InputConnectorImpl[In2]
def conn2: InputConnector[In2] = conn2Impl // show to the outer world only InputConnector
registerConnectors(conn1Impl, conn2Impl)
override protected def calculateOutput(): Option[Out] = {
for {v1 <- conn1Impl.currentValue
v2 <- conn2Impl.currentValue}
yield func(v1, v2)
}
}
// add more RxCalculationN if needed
And you can use it like this:
def test(): Unit = {
val pipe2 = new RxCalculation1((in: Double) => {
println(s"in = $in")
val vel = 3.4
val V = 300
val a = 10.2
val TotV = V + in
TotV * a / vel
})
val in1 = new RxValue(2.0)
println(pipe2.currentValue)
val conn1 = pipe2.conn1.connectInput(in1)
println(pipe2.currentValue)
in1.value = 3.0
println(pipe2.currentValue)
conn1.disconnect()
println(pipe2.currentValue)
}
which prints
None
in = 2.0
Some(905.9999999999999)
in = 3.0
Some(909.0)
None
Here your "pipe" is RxCalculation1 (or other RxCalculationN) which wraps a function and you can "connect" and "disconnect" other "pipes" or just "values" to various inputs and start a chain of updates.
Is there a simple way to return a concrete type in an override method? And what about creating an instance of a concrete implementation? And calling chained methods implemented in the concrete class, so they return a correct type, too? I have a solution (based on https://stackoverflow.com/a/14905650) but I feel these things should be simpler.
There are many similar questions, but everyone's case is a little different, so here is another example (shortened from https://github.com/valdanylchuk/saiml/tree/master/src/main/scala/saiml/ga). When replying, if possible, please check if the whole code block compiles with your suggested change, because there are subtle cascading effects. I could not make this work with the "curiously recurring template pattern", for example (not that I find it nicer).
import scala.reflect.ClassTag
import scala.util.Random
abstract class Individual(val genome: String) {
type Self
def this() = this("") // please override with a random constructor
def crossover(that: Individual): Self
}
class HelloGenetic(override val genome: String) extends Individual {
type Self = HelloGenetic
def this() = this(Random.alphanumeric.take("Hello, World!".length).mkString)
override def crossover(that: Individual): HelloGenetic = {
val newGenome = this.genome.substring(0, 6) + that.genome.substring(6)
new HelloGenetic(newGenome)
}
}
class Population[A <: Individual {type Self = A} :ClassTag]( val size: Int,
tournamentSize: Int, givenIndividuals: Option[Vector[A]] = None) {
val individuals: Vector[A] = givenIndividuals getOrElse
Vector.tabulate(size)(_ => implicitly[ClassTag[A]].runtimeClass.newInstance.asInstanceOf[A])
def tournamentSelect(): A = individuals.head // not really, skipped
def evolve: Population[A] = {
val nextGen = (0 until size).map { _ =>
val parent1: A = tournamentSelect()
val parent2: A = tournamentSelect()
val child: A = parent1.crossover(parent2)
child
}.toVector
new Population(size, tournamentSize, Some(nextGen))
}
}
class Genetic[A <: Individual {type Self = A} :ClassTag](populationSize: Int, tournamentSize: Int) {
def optimize(maxGen: Int, maxMillis: Long): Individual = {
val first = new Population[A](populationSize, tournamentSize)
val optPop = (0 until maxGen).foldLeft(first) { (pop, _) => pop.evolve }
optPop.individuals.head
}
}
The CRTP version is
abstract class Individual[A <: Individual[A]](val genome: String) {
def this() = this("") // please override with a random constructor
def crossover(that: A): A
}
class HelloGenetic(override val genome: String) extends Individual[HelloGenetic] {
def this() = this(Random.alphanumeric.take("Hello, World!".length).mkString)
override def crossover(that: HelloGenetic): HelloGenetic = {
val newGenome = this.genome.substring(0, 6) + that.genome.substring(6)
new HelloGenetic(newGenome)
}
}
class Population[A <: Individual[A] :ClassTag]( val size: Int,
tournamentSize: Int, givenIndividuals: Option[Vector[A]] = None) {
val individuals: Vector[A] = givenIndividuals getOrElse
Vector.tabulate(size)(_ => implicitly[ClassTag[A]].runtimeClass.newInstance.asInstanceOf[A])
def tournamentSelect(): A = individuals.head // not really, skipped
def evolve: Population[A] = {
val nextGen = (0 until size).map { _ =>
val parent1: A = tournamentSelect()
val parent2: A = tournamentSelect()
val child: A = parent1.crossover(parent2)
child
}.toVector
new Population(size, tournamentSize, Some(nextGen))
}
}
class Genetic[A <: Individual[A] :ClassTag](populationSize: Int, tournamentSize: Int) {
def optimize(maxGen: Int, maxMillis: Long): Individual[A] = {
val first = new Population[A](populationSize, tournamentSize)
val optPop = (0 until maxGen).foldLeft(first) { (pop, _) => pop.evolve }
optPop.individuals.head
}
}
which compiles. For creating the instances, I'd suggest just passing functions:
class Population[A <: Individual[A]](val size: Int,
tournamentSize: Int, makeIndividual: () => A, givenIndividuals: Option[Vector[A]] = None) {
val individuals: Vector[A] = givenIndividuals getOrElse
Vector.fill(size)(makeIndividual())
...
}
If you want to pass them implicitly, you can easily do so:
trait IndividualFactory[A] {
def apply(): A
}
class HelloGenetic ... // remove def this()
object HelloGenetic {
implicit val factory: IndividualFactory[HelloGenetic] = new IndividualFactory[HelloGenetic] {
def apply() = new HelloGenetic(Random.alphanumeric.take("Hello, World!".length).mkString)
}
}
class Population[A <: Individual[A]](val size: Int,
tournamentSize: Int, givenIndividuals: Option[Vector[A]] = None)
(implicit factory: IndividualFactory[A]) {
val individuals: Vector[A] = givenIndividuals getOrElse
Vector.fill(size)(factory())
...
}
I'm experimenting with Scala FastParsers library and I'm studying macro expanding of the following code:
val trueValue = "true".toCharArray
val falseValue = "false".toCharArray
object KParser1 {
import fastparsers.framework.implementations.FastParsersCharArray._
val kparser = FastParsersCharArray {
def func1: Parser[Any] = func1 | falseValue
}
}
Whole expanding is there but a piece of code from there really bothers me
while$2() {
if (inputpos$macro$2.$less(inputsize$macro$3).$amp$amp(input$macro$1(inputpos$macro$2).$eq$eq(' ').$bar$bar(input$macro$1(inputpos$macro$2).$eq$eq('\t')).$bar$bar(input$macro$1(inputpos$macro$2).$eq$eq('\n')).$bar$bar(input$macro$1(inputpos$macro$2).$eq$eq('\r'))))
{
inputpos$macro$2 = inputpos$macro$2.$plus(1);
while$2()
}
else
()
};
It looks like the code which skips whitespace from input stream but I can't infer what exactly is while$2: is it declared there as Unit => Unit and called automatically or is it some predefined function with type Unit => Any => Any?
It's just a loop. Compare:
scala> while (!done) println("working")
[[syntax trees at end of typer]] // <console>
package $line5 {
object $read extends scala.AnyRef {
def <init>(): $line5.$read.type = {
$read.super.<init>();
()
};
object $iw extends scala.AnyRef {
def <init>(): type = {
$iw.super.<init>();
()
};
import $line4.$read.$iw.$iw.done;
object $iw extends scala.AnyRef {
def <init>(): type = {
$iw.super.<init>();
()
};
private[this] val res0: Unit = while$1(){
if ($line4.$read.$iw.$iw.done.unary_!)
{
scala.this.Predef.println("working");
while$1()
}
else
()
};
<stable> <accessor> def res0: Unit = $iw.this.res0
}
}
}
}
I want to be able to write code like
10 times {
doSomething
}
So I thought I could do that with implicits.
When i execute the following code in the Scala REPL it gets defined correctly
scala> implicit def intToMyRichInt(count: Int) = {
| new {
| def times(f: => Unit) = {
| 1 to count foreach { _ => f }
| }
| }
| }
However when i try to compile,
object Test {
implicit def intToMyRichInt(count: Int) = {
new {
def times(f: => Unit) = {
1 to count foreach { _ => f }
}
}
}
it fails with the error
error: recursive method intToMyRichInt needs result type
1 to count foreach { _ => f }
What is the difference? What am I doing wrong?
After fix the code by removing the def's {, it compiled just fine:
scala> object Test {
| implicit def intToMyRichInt(count: Int) = {
| new {
| def times(f: => Unit) =
| 1 to count foreach { _ => f }
| }
| }
| }
defined module Test
It's also recommended to remove the {} after the implicit def:
object Test {
implicit def intToMyRichInt(count: Int) =
new {
def times(f: => Unit) =
1 to count foreach { _ => f }
}
}
Also, it's worth mentioning the new { ... class content ... } is actually a structural type to compiler, so invocations to times will be made reflectively. One work-around is to create a new class:
object Test {
class MyRichInt(x:Int) {
def times(f: => Unit) = 1 to x foreach { _ => f }
}
implicit def intToMyRichInt(count: Int) = new MyRichInt(count)
}
Hope to have answered your question.
#tbruhn: I could not verify your problem, it compiles fine here.
I suspect that you are using some outdated version of Scala maybe?
If that's the case, the obvious fix is upgrading to Scala 2.8.x!
Otherwise, how do you compile? If you are compiling via your IDE, try to see if scalac has the same error.
I think scala won't be able to infer return types for recursive functions for reasons that I once knew but now forget.
But in your case I can compile the file successfully except it misses one more }.
Unfortunately, workaround suggested by pedrofurla doesn't appear to work (at least in 2.8.0 final):
object Test {
implicit def intToMyRichInt(count: Int) =
new ScalaObject {
def times(f: => Unit) =
1 to count foreach { _ => f }
}
def foo = 10.times { println("foo") }
}
F:\MyProgramming\raw>scalac -Xprint:jvm Main.scala
[[syntax trees at end of jvm]]// Scala source: Main.scala
package <empty> {
final class Test extends java.lang.Object with ScalaObject {
final private <synthetic> <static> var reflParams$Cache1: Array[java.lang.Class] = Array[java.lang.Class]{classOf[scala.Function0]};
#volatile private <synthetic> <static> var reflPoly$Cache1: java.lang.ref.SoftReference = new java.lang.ref.SoftReference(new scala.runtime.EmptyMethodCache());
<synthetic> <static> def reflMethod$Method1(x$1: java.lang.Class): java.lang.reflect.Method = {
if (Test.reflPoly$Cache1.get().$asInstanceOf[scala.runtime.MethodCache]().eq(null))
Test.reflPoly$Cache1 = new java.lang.ref.SoftReference(new scala.runtime.EmptyMethodCache());
var method1: java.lang.reflect.Method = Test.reflPoly$Cache1.get().$asInstanceOf[scala.runtime.MethodCache]().find(x$1);
if (method1.ne(null))
return method1
else
{
method1 = x$1.getMethod("times", Test.reflParams$Cache1);
Test.reflPoly$Cache1 = new java.lang.ref.SoftReference(Test.reflPoly$Cache1.get().$asInstanceOf[scala.runtime.MethodCache]().add(x$1, method1));
return method1
}
};
implicit def intToMyRichInt(count$1: Int): ScalaObject = new Test$$anon$1(count$1);
def foo(): Unit = {
{
val qual1: ScalaObject = Test.this.intToMyRichInt(10);
{
{
var exceptionResult1: java.lang.Object = _;
try {
exceptionResult1 = Test.reflMethod$Method1(qual1.getClass()).invoke(qual1, Array[java.lang.Object]{{
(new Test$$anonfun$foo$1(): Function0)
}})
} catch {
case ($1$ # (_: java.lang.reflect.InvocationTargetException)) => {
exceptionResult1 = throw $1$.getCause()
}
};
exceptionResult1
};
scala.runtime.BoxedUnit.UNIT
}
};
()
};
def this(): object Test = {
Test.reflParams$Cache1 = Array[java.lang.Class]{classOf[scala.Function0]};
Test.reflPoly$Cache1 = new java.lang.ref.SoftReference(new scala.runtime.EmptyMethodCache());
Test.super.this();
()
}
};
#SerialVersionUID(0) #serializable final <synthetic> class Test$$anon$1$$anonfun*$1 extends scala.runtime.AbstractFunction1$mcVI$sp {
final def apply(x$1: Int): Unit = Test$$anon$1$$anonfun*$1.this.apply$mcVI$sp(x$1);
<specialized> def apply$mcVI$sp(v1: Int): Unit = Test$$anon$1$$anonfun*$1.this.f$1.apply$mcV$sp();
final <bridge> def apply(v1: java.lang.Object): java.lang.Object = {
Test$$anon$1$$anonfun*$1.this.apply(scala.Int.unbox(v1));
scala.runtime.BoxedUnit.UNIT
};
<synthetic> <paramaccessor> private[this] val f$1: Function0 = _;
def this($outer: Test$$anon$1, f$1: Function0): Test$$anon$1$$anonfun*$1 = {
Test$$anon$1$$anonfun*$1.this.f$1 = f$1;
Test$$anon$1$$anonfun*$1.super.this();
()
}
};
final class Test$$anon$1 extends java.lang.Object with ScalaObject {
def times(f$1: Function0): Unit = scala.this.Predef.intWrapper(1).to(Test$$anon$1.this.count$1).$asInstanceOf[scala.collection.immutable.Range$ByOne]().foreach$mVc$sp({
(new Test$$anon$1$$anonfun*$1(Test$$anon$1.this, f$1): Function1)
});
<synthetic> <paramaccessor> private[this] val count$1: Int = _;
def this(count$1: Int): Test$$anon$1 = {
Test$$anon$1.this.count$1 = count$1;
Test$$anon$1.super.this();
()
}
};
#SerialVersionUID(0) #serializable final <synthetic> class Test$$anonfun$foo$1 extends scala.runtime.AbstractFunction0$mcV$sp {
final def apply(): Unit = Test$$anonfun$foo$1.this.apply$mcV$sp();
<specialized> def apply$mcV$sp(): Unit = scala.this.Predef.println("foo");
final <bridge> def apply(): java.lang.Object = {
Test$$anonfun$foo$1.this.apply();
scala.runtime.BoxedUnit.UNIT
};
def this(): Test$$anonfun$foo$1 = {
Test$$anonfun$foo$1.super.this();
()
}
}
}