4

Is there any relationship between this aliasing and self type? Is this aliasing a special case of self type? In programming in scala 2nd P776, the author said:

abstract class Parser[+T] extends ... { p =>

You saw syntax like this in Section 29.4, where it was used to give a self type to a trait.

but, the syntax for self type doesn't look like this, it's like:

this:SomeAssumedType =>

And another question is why this aliasing is useful? I can't see there's any sense to give this reference an alias, because it's already a conventional alias for the current object reference, however in the Play framework source code, I saw lots of codes (especially, the anorm part) like:

trait RowParser[+A] extends (Row => SqlResult[A]) {

parent =>

Why does this make sense?

Sawyer
  • 15,581
  • 27
  • 88
  • 124
  • Similar: http://stackoverflow.com/questions/8073263/explicit-self-references-with-no-type-difference-with-this – Philippe May 31 '12 at 16:12
  • @Philippe What I really want to know is why it is necessary to alias the this reference. I know `p =>` is a reference for `this`, but I don't see there is any point, thus I can't use it in my code, and maybe miss something from reading others' codes. – Sawyer Jun 01 '12 at 07:44
  • Right. As explained in the answers to both questions, it's useful when you need a reference to enclosing class from an inner class. – Philippe Jun 01 '12 at 12:30
  • @Philippe this also suggested in `Programming In Scala`, but the usage in Play framework source code didn't have any inner class, maybe that's just not a good example of this usage. – Sawyer Jun 01 '12 at 13:44

1 Answers1

4

You can have a self-type and this aliasing at the same time:

abstract class Parser[+T] { p: SomeAssumedType => … }

If you don’t include a type ascription, Scala will assume that the type of the variable is the type of the surrounding class, thus giving you a simple alias for this.

If you keep the name this with the ascription, then Scala expects you to initialise this class in a way that the ascription can be fulfilled.

As for the this aliasing. Here’s the situation in which this is needed:

object OuterObject { outer =>
  val member = "outer"
  object InnerObject {
    val member = "inner"
    val ref1 = member
    val ref2 = this.member
    val ref3 = outer.member

    def method1 = {
      val member = "method"
      member
    }
    def method2 = {
      val member = "method"
      this.member
    }
    def method3 = {
      val member = "method"
      outer.member
    }
  }
}

scala> OuterObject.InnerObject.ref1
res1: java.lang.String = inner

scala> OuterObject.InnerObject.ref2
res2: java.lang.String = inner

scala> OuterObject.InnerObject.ref3
res3: java.lang.String = outer

scala> OuterObject.InnerObject.method1
res4: java.lang.String = method

scala> OuterObject.InnerObject.method2
res5: java.lang.String = inner

scala> OuterObject.InnerObject.method3
res6: java.lang.String = outer
Debilski
  • 66,976
  • 12
  • 110
  • 133