4

In the following code:

object MyObj {
  private[this] def myMethod = .....
}

My understanding of the this modifier to the access modifiers (private, public... etc.,) is that the presence of this makes it specific to that instance! In the case above we only have one instance. So isn't this redundant?

joesan
  • 13,963
  • 27
  • 95
  • 232
  • possible duplicate of [private\[this\] vs private](http://stackoverflow.com/questions/9698677/privatethis-vs-private) – Suma May 08 '15 at 07:18

4 Answers4

9

A private member (which is called class-private) is accessible from both the class and its companion object. A private[this] member (called object-private) is truly not accessible from outside the companion object.

class MyObj {
  MyObj.classPrivate
  MyObj.objectPrivate // error: symbol is not accessible
}
object MyObj {
  private def classPrivate = ???
  private[this] def objectPrivate = ???
}

So in short, the keyword is not redundant here.

dwickern
  • 3,519
  • 1
  • 14
  • 21
4

The qualifier disables generation of accessors:

scala> object X { private var v = 42 ; def x = v * 2 }
defined object X

scala> object Y { private[this] var v = 42 ; def x = v * 2 }
defined object Y

scala> :javap -pr X
Binary file X contains $line3.$read$$iw$$iw$X$
Compiled from "<console>"
public class $line3.$read$$iw$$iw$X$ {
  public static final $line3.$read$$iw$$iw$X$ MODULE$;
  private int v;
  public static {};
  private int v();
  private void v_$eq(int);
  public int x();
  public $line3.$read$$iw$$iw$X$();
}

scala> :javap -pr Y
Binary file Y contains $line4.$read$$iw$$iw$Y$
Compiled from "<console>"
public class $line4.$read$$iw$$iw$Y$ {
  public static final $line4.$read$$iw$$iw$Y$ MODULE$;
  private int v;
  public static {};
  public int x();
  public $line4.$read$$iw$$iw$Y$();
}

scala> :javap -prv X#x
  public int x();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #24                 // Method v:()I
         4: iconst_2      
         5: imul          
         6: ireturn       
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       7     0  this   L$line3/$read$$iw$$iw$X$;
      LineNumberTable:
        line 7: 0

scala> :javap -prv Y#x
  public int x();
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0       
         1: getfield      #18                 // Field v:I
         4: iconst_2      
         5: imul          
         6: ireturn       
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       7     0  this   L$line4/$read$$iw$$iw$Y$;
      LineNumberTable:
        line 7: 0
som-snytt
  • 39,429
  • 2
  • 47
  • 129
  • I am curious to know more about this: Is there some reason why is this so? Is this a common reason for writing private[this] in a code? Is this documented somewhere? – Suma May 07 '15 at 08:25
  • @Suma The optimization is not specified but is mentioned here http://twitter.github.io/effectivescala/ and http://stackoverflow.com/questions/9698677/privatethis-vs-private – som-snytt May 07 '15 at 17:15
1

Strictly speaking, it isn't redundant because it forbids access from its companion class, which can access normal private members.

More importantly, that's completely besides the point. For the sake of the argument, let's say it is redundant. Should private[this] be forbidden on objects just because it is redundant? That would be very much against the design principles of the language!

One of the things Odersky wanted for Scala is to get rid of arbitrary restrictions, and that shows in all sorts of ways. What things can have nested declarations? Everything that can have declarations: functions, traits, classes and objects. And, latter, package objects. What can be nested on it? Again, almost everything (the exception being package objects, because they are also packages, and packages are not members or declarations). Where can you apply visibility options? On any declaration that is a member of a type (because only types have members). And so on.

In summary, while this particular case is not redundant, the language design doesn't frown on redundant declarations.

Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
0

You're right, semantically, but there might be some optimizations that aren't applied for private-without-this (though they probably could be). Hopefully someone else can nail the optimization question down.

Ed Staub
  • 15,480
  • 3
  • 61
  • 91