JRuby ベロシティ

2007年1月19日

昨日、テンプレートとマクロについて探求するためにベロシティを使う必要がありました。私はベロシティのシンプルなテンプレート言語が好きですが、Javaまたは.NETのコンテキストで使用していない場合がありました。その場合、ベロシティの使用は少し面倒になります。なぜなら、コンテキストを設定してJavaでプロセッサを実行しなければならないからです。

このような状況ではスクリプト言語が必要になりますが、私はRubyスクリプト言語を好みます。したがって、これはJRubyを試すのに最適なケースだと考えました。結論としては、大変便利です。しかも、私はその詳細にうんざりするでしょう。

JRubyをダウンロードして/usr/local/libに解凍し、/usr/local/lib/jrubyでアクセスできるようにシンボリックリンクを作成しました。

その後、/usr/local/binに簡単なリダイレクトシェルのシェルスクリプトを配置しました。

JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun
JRUBY_HOME=/usr/local/lib/jruby

/usr/local/lib/jruby/bin/jruby "$@"

これでJRubyを実行できるようになりました。

$ jruby -v
ruby 1.8.5 (0) [java]

(実際、動作するまで時間がかかりましたが、最終的に椅子とキーボードの間にバグがあることが分かりました。その内容をお伝えするのが恥ずかしいくらいです。)

ベロシティを実行するには、JRubyのクラスパスに追加する必要があります。

CLASSPATH=path/to/velocity-dep-1.4.jar
export CLASSPATH
jruby "$@"

ベロシティを実行するために小さなヘルパークラスを作成しました。

require 'java'

class VelocityLauncher
  def initialize context, template
    @context = context
    @template = template
  end

  include_class 'org.apache.velocity.app.Velocity'
  include_class 'org.apache.velocity.VelocityContext'
  include_class 'java.io.StringWriter'

  def run
    vc = VelocityContext.new(@context)
    writer = StringWriter.new
    Velocity.init
    Velocity.evaluate(vc, writer, "LOG", @template)
    return writer.getBuffer
  end
end

少しテンプレートを作成できます

This is an announcement from $host

Our chief weapons are:
#foreach ($w in $weapons) 
  - $w 
#end

入力するには、作成が容易なRubyハッシュだけです。

ct = {'host' => 'Cardinal Fang', 
  'weapons' => ['Fear', 'Surprise', 'Ruthless Efficiency']}
template = File.readlines('template.txt').join

puts VelocityLauncher.new(ct, template).run

これを、次の形式のコンテキストファイルを受け取る簡単なコマンドラインランナーに拡張できると想像できます。

host = 'Cardinal Fang'
weapons = ['Fear', 'Surprise', 'Ruthless Efficiency']

しかし、現在は必要ありません。別の日にやることにします(「別の日の」の束縛は確かです)。