Scala REPL实现原理与Spark Shell简介

本文探讨Scala REPL的工作原理,从启动过程到代码执行,包括`process`、`createInterpreter`和`loopPostInit`关键方法。同时,介绍了Spark Shell如何基于Scala REPL构建,特别是在Scala 2.12之后的变化。文章还提到了Scala REPL参数,如`-noverify`和`-classpath`,以及Spark Shell如何预加载环境以提供便捷的交互体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Scala REPL实现原理与Spark Shell简介

版权声明:本文为博主原创文章,未经博主允许不得转载。

手动码字不易,请大家尊重劳动成果,谢谢

作者:http://blog.youkuaiyun.com/wang_wbq

Scala是我最喜欢的语言之一,与Java语言不同,Scala语言十分简洁,自带了很多的算子可以帮助我以最快的时间去实现我要实现的功能,因此可以留出更多的时间来进行思考。还有一点就是Scala提供了Scala REPL,在我不确定一个算子的功能时,我可以很快打开REPL进行验证,并直观得到答案。

由于Scala提供了REPL(ReadEvalPrint Loop),但是它并不是一门解释性语言,下面我们进入Scala REPL源码中来一探究竟。

Scala REPL

打开Scala REPL很简单,在安装好Scala的机器的命令行里输入Scala即可打开Scala REPL:

这里写图片描述

这里系统打开的是path中的scala命令,windows中为scala.bat。打开scala安装目录下的bin文件夹找到这两个文件。在文件中,我们都可以看到它的启动类:scala.tools.nsc.MainGenericRunner。因此我们从这个类入手,对Scala REPL源码进行简单的分析。

val howToRun = targetAndArguments match {
  case Nil      => AsRepl
  case hd :: _  => waysToRun find (_.name == settings.howtorun.value) getOrElse guessHowToRun(hd)
}

def runTarget(): Either[Throwable, Boolean] = howToRun match {
  case AsObject =>
    ObjectRunner.runAndCatch(settings.classpathURLs, thingToRun, command.arguments)
  case AsScript =>
    ScriptRunner.runScriptAndCatch(settings, thingToRun, command.arguments)
  case AsJar    =>
    JarRunner.runJar(settings, thingToRun, command.arguments)
  case Error =>
    Right(false)
  case _  =>
    // We start the repl when no arguments are given.
    Right(new interpreter.ILoop process settings)
}

我们可以看到,在scala命令为无参的情况下会打开Right(new interpreter.ILoop process settings),这就是Scala REPL的入口了,我们继续进入到process方法中一探究竟:

 // start an interpreter with the given settings
 def process(settings: Settings): Boolean = savingContextLoader {
   this.settings = settings
   createInterpreter()

   // sets in to some kind of reader depending on environmental cues
   in = in0.fold(chooseReader(settings))(r => SimpleReader(r, out, interactive = true))
   globalFuture = future {
     intp.initializeSynchronous()
     loopPostInit()
     !intp.reporter.hasErrors
   }
   loadFiles(settings)
   printWelcome()

   try loop() match {
     case LineResults.EOF => out print Properties.shellInterruptedString
     case _               =>
   }
   catch AbstractOrMissingHandler()
   finally closeInterpreter()

   true
 }

 /** Create a new interpreter. */
 def createInterpreter() {
   if (addedClasspath != "")
     settings.classpath append addedClasspath

   intp = new ILoopInterpreter
 }

 private def loopPostInit() {
   // Bind intp somewhere out of the regular namespace where
   // we can get at it in generated code.
   intp.quietBind(NamedParam[IMain]("$intp", intp)(tagOfIMain, classTag[IMain]))
   // Auto-run code via some setting.
   ( replProps.replAutorunCode.option
       flatMap (f => io.File(f).safeSlurp())
       foreach (intp quietRun _)
   )
   // classloader and power mode setup
   intp.setContextClassLoader()
   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值