Scala Reflection: how to list all variables in scope?

How can I list the names and / or values ​​of all "variables" (and not just vars) in a region / environment / binding?

To clarify, in the middle of the / script program or at some point in the REPL, I need to either (1) generate a list or (2) print a list of all the objects that can be accessed by Scala.

+5
source share
2 answers

The question can be interpreted broadly, but for example REPL supports some javax.script support with bound bindings:

 $ scala Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11). Type in expressions to have them evaluated. Type :help for more information. scala> val e = $intp.asInstanceOf[javax.script.ScriptEngine] e: javax.script.ScriptEngine = scala.tools.nsc.interpreter.ILoop$ILoopInterpreter@2b71fc7e scala> e.getContext res0: javax.script.ScriptContext = javax.script.SimpleScriptContext@63c12fb0 scala> e.getContext.getScopes res1: java.util.List[Integer] = [100, 200] scala> e.getContext.getBindings(100) res2: javax.script.Bindings = {} 

And REPL itself saves the requested area, representing the history of the current session, which is automatically imported into the current line of the script:

 scala> $intp.replScope res3: $intp.global.Scope = Scopes(value $intp, value e, value res0, value res1, value res2) 

It is also possible to implement the REPL termination mechanism:

 scala> :power ** Power User mode enabled - BEEP WHIR GYVE ** ** :phase has been set to 'typer'. ** ** scala.tools.nsc._ has been imported ** ** global._, definitions._ also imported ** ** Try :help, :vals, power.<tab> ** scala> reader.completion res4: scala.tools.nsc.interpreter.Completion = scala.tools.nsc.interpreter.JLineCompletion@68b7bdcb scala> res4.completer.complete("",0) res6: scala.tools.nsc.interpreter.Completion.Candidates = Candidates(0,List($intp, $ires0, $ires1, $ires10, $ires11, $ires12, $ires13, $ires14, $ires15, $ires16, $ires17, $ires18, $ires2, $ires3, $ires4, $ires5, $ires6, $ires7, $ires8, $ires9, $r, AND, BLOCK, CASE, DEFAULT, FALSE, IF, LIT, NEW, NOT, NULL, REF, SOME, SelectStart, TRUE, TRY, UNIT, ZERO, analyzer, classOf, completion, e, fn, global, history, intp, isettings, lastRequest, mkTreeFromSelectStart, mkTreeMethods, mkTreeMethodsFromSelectStart, mkTreeMethodsFromSymbol, nullSafe, phased, power, r, reader, repl, replImplicits, res0, res1, res2, res3, res4, returning, scala$tools$nsc$ast$TreeDSL$CODE$$$outer, treedsl, typed, typer, vals)) scala> 

A separate tab in the REPL console offers an autocomplete function, which here shows all the unwanted files in my current directory, which by default is in the class path:

 $ scala Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11). Type in expressions to have them evaluated. Type :help for more information. scala> $intp broken enumtest inheritthewind maker oracle sbtbomb thingy P bumper erased inlined mangled orelse scala throwgen Q butwhen exh inliner mapeach org scallop thrownull SO22581163 bytype eyeshadow inner maqicode othercase scrap tiles _root_ callbacks fany inputcheck matchprim out scripts timezone a capture featureless intcake maybeamb overdone searchme tmp abjectfuture cce ff interp maykov overnullary selfpub toString absval cdtest fielding interpat metamac pathmaker seqto tops adaptation charmatch filloval intpbind mkarray peasy serialmigration trial akka choosy filrdr intupolated mksym pet serious tribool algedu classOf findwidgets invokeFrom modtest petconfig shapelessed tricks angeldance classmatch finf isInstanceOf myanno phyl simple-swing trivial annee classy fixedimp isanon mydays pickit singleton tryxform annie cmpprs fixes isfun myintp pimpin slider tstest annoconst coltfred fixme isscala mypkg pkginvoke slow typeref annot com flib java mypriv plugincp smtest tztest anymember compilit foodir javafx nestedmain plugs sobral unapplynull anything convprs fooplus javax netscape pointers somatch unavail applied copier for29 jbyte newfrom pointopt some_package unensured arrow corner formac jdk nextcompleted pos sortitout unused asInstanceOf counted ftw jex niolock poster sounds updater atrait countints funk jext noany pow specbug valdef autoenum cr funkstr jline noapp preferthunk speck vec auxctor ctag futfilter jmap nodep prettycase splitat version bad-scales curtest futuremap jover nofeature primover stale vowelshift badXlint cyclic fval jperms nofuture printer statik w badaccess dbadd gline junk noimp privctor str2int warnadapt badbob default-tparam global k noinline privover strtyp weakerr badgeneric delayed goodbye kcharex nointerp procked structural-return welper badimp delayedsignal gr keptstar nonl protcase stupid whose badinherit delineate grapher kmap norec protval succinctly widgets badmap demoapi groupby lazyparadox nosehorn publicity sun wrappedarray badmatch dep guiced lazyside nothingannot q superduper wtf badover doc guy lazysplit ns qqparms sxema x badoverride dockable halfinterval lib nts quickly syncd xmladd badpath dosth here liner nullgroup quoterep syshook xmlex badpkg doublearrow hidden linetest nullpair rawj t1 xmlregex badseal dummyonly hiddenimport linted nulltype raws t1807 xmlreplace badstrimp dynospec id linty nummaker reader t5148 xmlsub badvargs earlier imparted lit off reflectenum t5589 xmlt badvol eatery imparter littlecake oiler5 replslow t7121 xxx bigmethod email impctx looker old-and-blue repro t7775 zed binder empty impless lookit oldname required t8433 biterpolator emptypackage impmag lookup om sample-foo tabpane blocking enclosing imptest loopy oneq samplewarn taggedparam blownfuture enclosingcls imptrait macinfer oops saver target bounded enpatch include macvar optdate sbt-test teachers scala> 
+3
source

This cannot be done at runtime - at least not the way you want, because the JVM is not organized as a giant symbol table, updated after each state, which you can query at any time and find named objects as you name them ( and I think this is true for languages ​​and environments).

You can try to query for what is really organized as a table, such as class / interface methods, but you must know the full class name before making the query. To give you a quick example of how class loading works, the JVM cannot even list which classes you can create, because new ones can be created on the fly or obtained from some kind of repository. Take another example: import does not even exist at runtime ...

You need to narrow down your requirements. For example, if you target REPL, you can (but the effort will be huge) to modify it to spoil its internal data structures. Similarly, if you are targeting a script and have access to sources, you can theoretically modify the compiler with a plugin that does the necessary work. Be warned that I only mentioned these things, but would never have thought of doing it myself, because it will take a lot of effort, and I do not see a real need.

+1
source

Source: https://habr.com/ru/post/1201601/


All Articles