Using private [this] for a member of an object in Scala

In the following code:

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

      

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

+3


source to share


4 answers


The qualifier disables the generation of accessories:



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

      

+3


source


A private

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

(called object-private) is really 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 the keyword is not redundant here.

+8


source


Strictly speaking, it is not redundant, because it disallows access from its companion class, which can access normal private members.

More importantly, it is completely apart from the point. For the sake of an argument, let's say it's superfluous. Should it private[this]

be banned on sites just because it is redundant? That would be very much against the principles of language design!

One of the things Odersky wanted for Scala was to get rid of arbitrary constraints, and this manifests itself in many different ways. What things can nested ads have? Anything that can have a declaration: functions, traits, classes and objects. Finally, the package objects. What can you invest in it? Again, almost everything (except for package objects because they are also packages, and packages are not members or declarations). Where can you apply visibility options? In any declaration that is a member of a type (since only types have members). Etc.

Thus, while this particular case is not redundant, the design of the language is not frowned upon by unnecessary declarations.

+1


source


You are correct, semantically, but there might be some optimizations that don't apply for private-without-this (although they probably can). Hopefully someone else can fix the optimization problem.

0


source







All Articles