HRJ
HRJ

Reputation: 17767

How to define a field in Scala?

Is there a way to force a class member to be a public field in Scala?

class X { val number = 0 }

I want number to be a public field; I don't want the default behaviour of a private field with getter / setter.

The only discussion that I can find is this, but there is no conclusive answer.

Thanks!

Edit: My particular use-case is to access the field via a scripting engine (Rhino/Nashorn). Though I would prefer to have a solution that is more general.

Upvotes: 2

Views: 290

Answers (3)

som-snytt
som-snytt

Reputation: 39577

Modulo name mangling:

scala> object X { private[this] val x = 7 ; @inline def getX = x }
defined object X

scala> :javap -prv X
Binary file X contains $line5.$read$$iw$$iw$X$
[snip]
{
  public static final $line5.$read$$iw$$iw$X$ MODULE$;
    flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL

  public final int $line5$$read$$iw$$iw$X$$x;
    flags: ACC_PUBLIC, ACC_FINAL

Inlining the accessor loosens access to the field, which is name-mangled to avoid clashes. The odd name here is due to REPL templating.

Without REPL:

scala> classOf[x.X$].getDeclaredFields map (f => s"'${f.getName}'")
res1: Array[String] = Array('MODULE$', 'x$X$$x')

The normal private field is name-mangled in Scala reflection by appending a space; at least this mangling is visible to the naked eye.

Upvotes: 1

The Archetypal Paul
The Archetypal Paul

Reputation: 41749

Since Java's Javascript binding is based on Rhino and the Rhino interpreter maps.. = XXX to getXXX and XXX = foo to setXXX(foo), if you mark the val with @BeanProperty, it should "just work".

Looks like Nashorn (Javascript in Java8) does the same thing: winterbe.com/posts/2014/04/05/java8-nashorn-tutorial (search for "working with getters and setters"), so you should be future-proof, too.

Upvotes: 2

Schuiram
Schuiram

Reputation: 301

You usually can see those vals by default - as they are public by default. You do not need setter and getter.

class TestIt {
    val normalClassVariable = 10
}

class CanYouSeeIt{
  var test:TestIt = new TestIt
  test.normalClassVariable
}

This works perfectly fine.

Edit: If you need more insight, try this link: http://daily-scala.blogspot.ch/2009/11/access-modifiers-public-private.html

Upvotes: -1

Related Questions