2

Suppose I have a private[stuff] method Stuff.something in org.my.stuff. Is there something that I can do in the Scala REPL so that I can call Stuff.something without getting the error error: value something is not a member of org.my.stuff.Stuff?

In particular, can I get the REPL to be "inside" a given package (here org.my.stuff), giving access to its private members?

mitchus
  • 4,677
  • 3
  • 35
  • 70
  • 1
    Well... `private` things mean that they are `private` and there is nothing that you can do about it. But more important is that you `should not` be trying to do that. – sarveshseri Feb 06 '17 at 12:45
  • You can add some code in the same package and call that using REPL. – sarveshseri Feb 06 '17 at 12:47
  • Possible duplicate of [How do I read a private field in Java?](http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java) – Zang MingJie Feb 06 '17 at 12:50
  • @SarveshKumarSingh correction, I mean `private[stuff]`; editing – mitchus Feb 06 '17 at 12:55
  • @SarveshKumarSingh, I think that's a bit overstating it. It would be good to have a way of doing it from the REPL, under controlled conditions. In the final code, I agree with yout. – The Archetypal Paul Feb 06 '17 at 14:46

1 Answers1

6

Using "packages" in the REPL

You cannot get a REPL prompt "inside" a given package, see https://stackoverflow.com/a/2632303/8261

You can use "package" statements inside ":paste -raw" mode in the REPL (see e.g. http://codepodu.com/paste-mode-in-scala-repl/ for docs)

For example, if you had code like:

package org.my.stuff {
  object Stuff {
    private[stuff] val something = "x"
  }
}

You could declare a helper class in the same package using ":paste -raw" mode, i.e.

scala> :paste -raw
// Entering paste mode (ctrl-D to finish)

package org.my.stuff {
  object StuffAccessHelper {
    def something = Stuff.something
  }
}

// Exiting paste mode, now interpreting.


scala> org.my.stuff.StuffAccessHelper.something
res11: String = x

How to access any members using setAccessible

You can always fall back on the full "setAccessible" reflection incantation, as described at How do I read a private field in Java?

Using the same prior code as above, you can access org.my.stuff.Stuff.something like:

scala> val f = org.my.stuff.Stuff.getClass.getDeclaredField("something")
f: java.lang.reflect.Field = private final java.lang.String org.my.stuff.Stuff$.something

scala> f.setAccessible(true)

scala> f.get(org.my.stuff.Stuff)
res10: Object = x
Community
  • 1
  • 1
Rich
  • 15,048
  • 2
  • 66
  • 119
  • A `private[stuff]` method in scala is compiled to a public method, because the JVM doesn't have such finegrained access modifiers like scala. And also, you can define packages in the REPL with `:paste -raw`. – Jasper-M Feb 06 '17 at 14:50
  • Thanks, @Jasper-M, I've updated my answer accordingly – Rich Feb 06 '17 at 15:51