Scala反射:如何列出作用域中的所有变量



如何列出范围/环境/绑定中所有"变量"(而不仅仅是变量)的名称和/或值?

为了澄清,在程序/脚本的中间或REPL的某个时刻,我需要(1)生成一个列表或(2)打印Scala语句可以访问的所有实体的列表。

这个问题可以广义解释,但例如REPL对具有作用域绑定的javax.script有一些支持:

$ 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 = {}

REPL本身保留了一个可以查询的范围,表示自动导入当前脚本行的当前会话的历史:

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

也可以使用REPL的完成机制:

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> 

REPL控制台中的一个选项卡提供了自动完成功能,它在这里显示了我当前目录中的所有垃圾,默认情况下在类路径上:

$ 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> 

这在运行时是不可能做到的,至少不是你想要的方式,因为JVM并没有被组织成一个在每次语句后更新的巨大符号表,你可以随时查询并找到你所称的命名实体(我认为这在各种语言和环境中都是正确的)。

您可以尝试查询确实组织为表的东西,比如类/接口的方法,但在进行查询之前,您必须知道类的完全限定名称。举个简单的例子,根据类加载的工作方式,JVM甚至无法枚举您可以创建的类,因为新的类可以动态创建,也可以从某个存储库中检索。再举一个例子,import在运行时根本不存在。。。

你必须缩小你的要求。例如,如果您以REPL为目标,您可能能够(但需要付出巨大的努力)对其进行修改,以破坏其内部数据结构。类似地,如果你以脚本为目标并可以访问源代码,理论上你可以用一个能完成你需要的工作的插件来修改编译器。请注意,我只提到了这些事情,但永远不会考虑自己做这样的事情,因为这需要付出很多努力,我看不出有什么真正的需要。

相关内容

  • 没有找到相关文章

最新更新