Juan Paulo Salvador Juan Paulo Salvador - 2 months ago 21
Scala Question

scala - trying to print overridden toString method

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

Answer

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