Ruby
Opal

OpalとRubyに両対応したgemを作る

More than 3 years have passed since last update.

JavaScriptで書かれたRuby処理系、Opal http://opalrb.org/ の話です。

Node.jsのメリットの一つとして、「ロジック部分のコードをサーバとクライアントで共有できる」という点が挙げられたりします。
Opalを使うとRubyのコードをJSにコンパイルできるので、「Rubyで書かれた1つのコードを、サーバ上でもクライアント上でも動かす」ということができます。

以下は具体的な方法です。

gemの作り方

fooというgemを作って、RubyとOpalから使いたいとする。

  • foo.gemspec
    • 普通に書く。
  • lib/foo.rb
    • ここにライブラリ定義を書く。 これはRubyからもOpalからも読み込まれる可能性があるので、Opalで使えない機能は使ってはいけない(Kernel#systemとか)
  • lib/foo/opal.rb
    • 以下のように書く(意味は後述) Opal.append_path File.expand_path('../', File.dirname(__FILE__))

Rubyから使う

Rubyから使う場合、Gemfileにgem "foo"と書き、コード内ではrequire "foo"する。(要するに普通のgemを使う場合と同じですね)

Opalから使う

Opalから使う場合、Gemfileにgem "foo"と書くのは同じだけど、その先がちょっと異なる。

まずOpalコード内にはrequire "foo"と書きます。ただこれだけだとOpalのロードパスにfoo.rbがないのでエラーになる。

ここで、先ほど作っておいたlib/foo/opal.rbの出番です。
OpalプロジェクトのRuby側(たとえばconfig.ru)にrequire "foo/opal"と書いてください。

これで、Opalのロードパスにfoo gemのlib/以下が登録されるので、Opalコード内でrequire "foo"と書くことでfoo gemのlib/foo.rbを使うことができます。