小ネタ系エントリ。
Groovyでちょっとした作業をこなすためのスクリプトを書いていて、設定ファイル的なものを読み込ませて処理を切り替えたいと思った時に、こんなことをしてみましたよということで。
Groovyで設定ファイルを使うなら、ConfigSlurperというものが便利らしいです。
ConfigSlurper
http://groovy.codehaus.org/ConfigSlurper
でも、できれば処理そのものをクラス定義して切り替えたいなぁと思い、JSR-223を使うことにしました。
つまり、こういうこと。
呼び出し元。
caller.groovy
import javax.script.ScriptEngineManager def manager = new ScriptEngineManager() def engine = manager.getEngineByName('Groovy') def helloClass = engine.eval(new File('hello.groovy').text) def hello = helloClass.newInstance() hello.say()
呼び出される側。
hello.groovy
class Hello { def say() { println('Hello Groovy!') } }
ScriptEngine#eval時にClassクラスが返ってきているようなので
def helloClass = engine.eval(new File('hello.groovy').text)
これをnewInstanceして実行しました。
def hello = helloClass.newInstance()
で、実際に自分が使った時には、こんな感じでインターフェースを設けて使ってみました。
launcher.groovy
import javax.script.ScriptEngineManager def manager = new ScriptEngineManager() def engine = manager.getEngineByName('Groovy') def executeScripts = args executeScripts.each { script -> def executorClass = engine.eval(new File(script).text) def executor = executorClass.newInstance() executor.execute() } interface Executor { public void execute() }
呼び出される側。
executors/hello-executor.groovy
class HelloExecutor implements Executor { @Override public void execute() { println('Hello Groovy!') } }
executors/greet-executor.groovy
class GreetExecutor implements Executor { @Override public void execute() { println('Greeting!!') } }
ディレクトリ構成はこんな感じ。
$ find launcher.groovy executors
launcher.groovy
executors
executors/hello-executor.groovy
executors/greet-executor.groovy
実行。
$ groovy launcher.groovy executors/hello-executor.groovy executors/greet-executor.groovy Hello Groovy! Greeting!!
定義したインターフェースが見えているようで、メソッドのオーバーライドがなかったりするとちゃんとエラーになってくれます。
*ダックタイピングでやってもいいわけですが…
小さなスクリプト用途なので、あんまり大仰な仕組みは要らないけど、定義だけじゃなくて実装も書きたいということでこんな方法を選びました。
…普通ならこうやる的な見落としがあるかもと思いつつ、ですが。