In Scala, this is both much harder and much simpler than in Python.
It is much harder, because of implicit conversions: for example, you can call the ->
method on a String
, even though neither String
nor any of its superclasses has a ->
method. But there is an implicit conversion from Any
to a type that does have a ->
method (called ArrowAssoc
), and so it is legal to call the ->
method on any object, because Scala will implicitly convert that object to ArrayAssoc
. That's why you can not just ask an object about its available methods, because the object doesn't know which implicit conversions might be in scope.
It is, however, also much easier, because the set of available selectors can always be determined statically, without actually having to run the code.
The Scala REPL implements completion using the Presentation Compiler, the implementation is in the class scala.tools.nsc.interpreter.resentationCompilerCompleter
. Maybe you can find some inspiration there. In general, the correct approach would be to use Scala Reflection and/or the Presentation Compiler.