ErlangとRubyの連携(Ruby -> Erlang編)

一つ前の記事で次はRubyからErlangを呼ぶ方法を調べるって書いてましたが、既にそれを説明してくれているページがありましたw うなの日記

とはいえ、ここは勉強だと思って自分なりにコードを書いて上記サイトを参考にさせて頂きながらまとめてみます。

RBridgeのインストール
さて、調べ始めていきなり、上記サイトで紹介されているRulang Bridgeが名前が変わってrbridgeとして管理されている事がわかり波乱の悪寒。。。
まずはgemで検索してみます。

$ gem search rbridge -r

*** REMOTE GEMS ***

rbridge (0.2.0)

0.2.0ですか...まあいいや、インストール。

$ sudo gem install rbridge

RBridgeサーバの起動
さて、ここでドキュメントを読むとrulangサーバを起動する為に以下を実行しろと言ってます。

$ rulang

起動スクリプトは/usr/local/binに入っているので、そこにパスが通ってれば起動出来るはずです。
が、、、起動せずw
なんか起動したっぽい感じに見えるのですがtelnetで調べるとデフォルトの9900番ポートはオープンしてませんOrz

気持ちが悪いですが、とりあえずその原因追及はあとにして、直接Erlangノードで起動してみます。
まずはErlang側のソースであるrulang.erlをコピーしてきてサーバを直接起動してみました。

$ cp /usr/local/lib/ruby/gems/1.9.1/gems/rbridge-0.2.0/rulang_server/rulang.erl ./
$ erl

起動したErlangノードでrulangサーバをコンパイルして起動してみる。

1> c(rulang).
{ok,rulang}
2> rulang:start_server(9900).

どうやら起動したっぽいです。telnetで9900番ポートに繋いでみたらオープンしてました。

Erlang標準モジュールをRubyから呼んでみる
では続いてRuby側から繋いでみます。以下のようなファイルを"ruby_client.rb"として保存します。

require "rubygems"
require "rbridge"

r_erlang = RBridge.new("erlang", "localhost", 9900)
p r_erlang.length([1,2,3,4,5,6,7,8,9])

保存したら実行。

$ ruby ruby_client.rb
9

結果が9と表示されました。
つまりRBridge.new(モジュール名, ホスト名, ポート番号)の第一引数でリモートからアクセスするErlangモジュールを文字列で指定します。自前のモジュールならここでそのモジュール名を指定すれば良いでしょう。

ホスト名、ポート番号は最初にErlang側でrulang:server/1を実行したホストとその際に引数で指定したポート番号を指定すれば良いです。


自作ErlangモジュールをRubyから呼んでみる
さて、コレだけじゃ面白くないので自前のErlangモジュールをRubyから呼んでみましょ。

まずは自前のErlangモジュールを用意。以下の内容のファイルを"erlang_server.erl"として保存します。

-module(erlang_server).
-export([hello/0, hello/1]).


hello() -> "hello".
    
hello(Name) -> 
    "hello " ++ Name.

あえて同じ名前の関数で引数の個数が違うものを1つづつ用意しました。

つづいてRuby側のソースは以下のものを"ruby_client.rb"として保存します。

require "rubygems"
require "rbridge"

erlang_server = RBridge.new("erlang_server", "localhost", 9900)
p erlang_server.hello
p erlang_server.hello("hiroe")

上記2つのファイルを作ったらまずはErlang側でRBridgeサーバを立ち上げます。このときRuby側から呼べるモジュールは手元のErlangノードが認識出来るモジュールになるのでパスを通しておくかノード上でコンパイルすればいい事になります。

Erlangノードを起動

$ erl

自作モジュールをコンパイルした後にrulang_serverを起動。

1> c(erlang_server).
{ok,erlang_server}
2> rulang:start_server(9900).
[RBridge Server Started]

では先ほど作成したRubyスクリプトを起動してみます。

$ ruby ruby_client.rb 
"hello"
"hello hiroe"

ばっちりこ!