Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escaping underscore for Java interoperability in Scala

Tags:

java

scala

Suppose I've got some Scala code that calls a Java library that uses _ as an identifier (and I do—it's a long story). Here's a simplified example:

public class StupidUnderscore {
  public static String _() { return "Please give me a real name!"; }
}

No problem, right? Just escape it:

scala> StupidUnderscore.`_`
res0: String = Please give me a real name!

And this has always worked, until I tried to update to Scala 2.10.2 this morning:

scala> StupidUnderscore.`_`
<console>:1: error: wildcard invalid as backquoted identifier
       StupidUnderscore.`_`
                        ^

This is due to a change that showed up in 2.10.1 and fixes this issue. From the commit message:

Prohibit _ as an identifier, it can only bring badness.

Well, sure, but I don't know why that means I can't escape it—I thought that's what backquotes were for.

Am I going to have to write a Java wrapper to get this to work? Is there some other way I can refer to a Java library's _ method in Scala?


As a footnote, I've confirmed that it's possible to work around this issue without writing any new Java:

object AwfulMacroHack {
  import scala.language.experimental.macros
  import scala.reflect.macros.Context

  def _impl(c: Context) = {
    import c.universe._
    c.Expr[String](
      Select(Ident(newTermName("StupidUnderscore")), newTermName("_"))
    )
  }

  def `I'm not named _!` = macro _impl
}

And then:

scala> AwfulMacroHack.`I'm not named _!`
res0: String = Please give me a real name!

I'm not sure this is any less horrible than the Java helper solution, though.

like image 319
Travis Brown Avatar asked Jul 25 '13 16:07

Travis Brown


People also ask

Is Scala fully interoperable with Java?

Scala source code compiles to Java bytecode, so it can execute on any JVM. It also provides complete interoperability with Java, and hence, we can reference Java from Scala and vice versa with ease.

What does underscore mean in Scala?

Scala allows the use of underscores (denoted as '_') to be used as placeholders for one or more parameters. we can consider the underscore to something that needs to be filled in with a value. However, each parameter must appear only one time within the function literal.


1 Answers

Since backticks are the mechanism for Java interop on identifiers (e.g. Thread.yield()), I doubt there's another way without using Reflection. I'd say your best bet (until the bug is fixed) is to write a static helper method in Java to access the _.

I know this is totally ridiculous, but it's probably still better than using reflection. They broke Java interop with that patch, so they'll have to address this issue eventually. Until they do, however, I think it's just broken.

like image 199
DaoWen Avatar answered Nov 09 '22 19:11

DaoWen