动态调用动态语言,第 2 部分: 在运行时寻找、执行和修改脚本
2009-11-19 00:00:00 来源:WEB开发网最后一个 scriptEngine.put() 调用让脚本可以通过 scriptExit 变量使用一个内部 helper 类(ScriptEarlyExit,见 清单 1)的实例。ScriptEarlyExit 定义了两个简单的方法 —— withMessage() 和 noMessage(),它们惟一的作用是抛出一个异常。如果脚本调用 scriptExit.withMessage() 或 scriptExit.noMessage(),那么方法抛出一个 ScriptEarlyExitException 异常。脚本引擎会捕捉这个异常、终止脚本处理并向调用脚本的 eval() 方法抛出一个 ScriptException 异常。
通过以这种迂回的方式提前退出脚本,就可以以一致的方式从函数或方法外的脚本处理过程返回。并非所有脚本语言都提供了这种方式所需的语句。例如,在 JavaScript 中,在执行高层代码时(这个示例应用程序中的抵押处理脚本正是采用这种构造方式),无法使用 return 语句。共享对象 scriptExit 解决了这个问题,一旦脚本判断出贷款人不符合抵押产品的要求,用任何语言编写的脚本都可以通过这个对象退出。
在 qualifyMortgage 中,对脚本引擎的 eval 方法的调用(见粗体代码)使用一个 try/catch 块捕捉 ScriptException 异常。catch 块中的代码检查 ScriptException 错误消息,从而判断这个脚本异常是由 ScriptEarlyExitException 造成的,还是由真正的脚本错误造成的。如果错误消息包含名称 ScriptEarlyExitException,那么代码就认为一切正常并忽略这个脚本异常。
这种在 Java 脚本编程 API 的脚本异常错误消息中搜索字符串的技术有点儿笨拙,但这对于本示例中使用的 Groovy、JavaScript 和 Ruby 语言解释器是有效的。如果所有脚本语言实现将从调用的 Java 代码抛出的 Java 异常添加到异常堆栈中,那么会更方便,这样就可以使用 Throwable.getCause() 方法获取这些异常。JRuby 和 Groovy 等解释器会这样做,但是内置的 Rhino JavaScript 解释器并不这样做。
更多精彩
赞助商链接