Reflection + String + reverse

Hello to everyone,

I need to resolve this question, I trying to execute with reflection some methods of String class, like ‘reverse’ but is not possible. Do you know if there any way to execute this? . Thank you… ;).

classOf[String].getMethod(“reverse”).invoke(result).asInstanceOf[String]

Regards,
JC

This can’t be easily done, because reverse is not a method on String, it’s a method on StringOps. The system automatically wraps the String in a StringOps when you call reverse, but that’s not the same thing as it actually being a method of String.

What are you trying to do? This sort of reflection-based code is unusual in Scala; possibly there’s a better way to accomplish the same goal…

The “reverse” method you are attempting to reflect on is not a member of
java.util.String. It is a member of StringLike, which Scala makes available
on java.util.String using (I think) implicit conversions.

let’s see what .reverse really does:

scala> reflect.runtime.universe.reify { "foo".reverse }
res7: reflect.runtime.universe.Expr[String] = Expr[String](Predef.augmentString("foo").reverse)

scala> augmentString("foo")
res8: scala.collection.immutable.StringOps = foo

ah, ok. so now:

scala> import collection.immutable.StringOps
scala> classOf[StringOps].getMethod("reverse").invoke(augmentString("foo")).asInstanceOf[String]
res9: String = oof
2 Likes

I was looking for to use something like “eval”, but scala don’t have support for this… Do you know if there any way to execute one method, of String for example, apart of reflection and obviously without to use the method directly

Thank you, probably I will use your code :slight_smile:

Correct – by and large, compiled languages (especially strongly-typed ones) are less likely to have “eval”-like capabilities. It’s not really what they are designed for.

Just one general warning: functionality like this can often leave gigantic security holes, especially if this code is exposed on the web. Use this sort of thing with a lot of care…

1 Like

Scala sort of has eval in its reflection API, however I wouldn’t advise to do this. This will probably also be the slowest way possible.

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> import scala.tools.reflect.ToolBox
import scala.tools.reflect.ToolBox

scala> val tb = ToolBox(runtimeMirror(getClass.getClassLoader)).mkToolBox()
tb: scala.tools.reflect.ToolBox[reflect.runtime.universe.type] = scala.tools.reflect.ToolBoxFactory$ToolBoxImpl@47c13b1d

scala> tb.eval(tb.parse(""" "foo".reverse """))
res10: Any = oof

Fair point, although I’ll note that that’s specific to ScalaJVM. None of this reflection-based stuff will work in ScalaJS…