LoginSignup
18
15

More than 5 years have passed since last update.

Ruby on ErlangVM in RubyKaigi2015 LT

Last updated at Posted at 2015-12-16

概要

RubyKaigi2015で、John Linさんという方が、ErRubyというErlangVM上で動くRuby実装のLT発表をされてました。興味深い内容でしたのでその紹介をします。

基本情報

ざっくりと言うと、ErlangVM上で動作するErRubyというRuby実装を作った(作っているよ)という内容です。

LTのスライドは以下のリンクからどうぞ。
What I learned by implementing a Ruby VM in Erlang

Githubのリポジトリは以下です。
erruby

目標はRubySpecを通す事だそうです。

アイデア

「ErlangのProcessをRubyのObjectとして扱えば良いんじゃね?」との事。

Erlang Process Ruby Object
コスト 低い,max=134,217,727 低い,全てがObject
通信方式 非同期通信 同期通信

example

簡単ですがRubyとErlangの関数呼び出しの比較になります。
Rubyが how_is_sushi? を同期呼び出ししているのに対して、Erlangは非同期で呼び出しています。

ruby_example
class Alice
  def chat_with_bob
    res = bob.how_is_sushi? # 1.invokeして結果を待つ 3.結果を受け取る
  end
end

class Bob
  def how_is_sushi? # 2.Idleで待機、messageを受けたらすしを返す、返したらIdle
    "すしわうまい"
  end
end
erlang_example
chat_with_bob(Bob) ->
  BoB ! {self(), 'how_is_sushi?'}, % 1.BoBにmessageを送信
  receive % 2.返信を待つ
    {ok, Message} -> Message % 6.返信を受け取る
  end.

bob_loop(State) ->
  receive
    {Sender, 'how_is_sushi?'} -> % 3.messageを受け取る
      Sender ! {ok, "すしわうまい"} % 4.返信する
  end,
  bob_loop(State). %5.待機

Ruby Object in Erlang

Objectに対するメソッド呼び出しは {send, <自身のprocess id>, ...} のメッセージを送信し、その返却は {method_result, <自分のprocess id>, ...} のメッセージを送信する事とすると、以下の様になります。

aliceからbobへの呼び出し

alice -> {send, , 'how_is_sushi?', []} -> bob

bobからaliceへの返却

alice <- {method_result, , "すしわうまい"} <- bob

self call method の問題

一見上手くいった様に見えますが、自身に対するメソッド呼び出し bob.sushi_score の場合に問題となります。

ruby_example
class Alice
  def chat_with_bob
    res = bob.is_sushi_good?
  end
end

class Bob
  def is_sushi_good?
    sushi_score > 90
  end

  def sushi_score
    9001
  end
end
erlang_example
chat_with_bob(Bob) ->
  Bob ! {self(), 'is_sushi_good?'}, % 1.Bobにメッセージを送信
  receive % 2.Bobからのメッセージを待つ
    {ok, Message} -> Message
  end.

bob_loop(State) ->
  receive
    {Sender, 'is_sushi_good?'} -> % 3.メッセージを受ける
      (self() ! ({self(), sushi_score}), % 4.自分自身(self)にメッセージを送信
      receive {ok, Score} -> % 5.Bobからのメッセージを待ち続ける!!!
        Sender ! {ok, Score > 90}
      end;
    {Sender, sushi_score} ->
      Sender ! {ok, 9001}
  end,
  bob_loop(State).

上記の sushi_score の様に、自分自身に対してメッセージを送信した場合、 %5 の様に自分自身のメッセージを待つ事になるので、この実装ではダメなわけです。

Ruby Method in Erlang

そこでどうするかというと、「RubyのMethodCallもErlangのProcessにすれば良い」です。

呼び出しイメージ

alice -> (spawn new process) -> {receiver, 'is_sushi_good?', arg, env, sender} -> (spawn new process) -> {receiver, sushi_score, arg, env, sender} -> ...

実装状況

ErRubyの実装状況としては、
- クラス定義
- ブロック・ローカル変数でのメソッドのeval
あたりまでとの事です。多分に実験的ではありますが、実装的にはなかなか面白そうです。興味のある方はコードを追ってみてはいかがでしょうか。

その他の実装に関する情報

ErlPortを使って、ErlangとRubyのブリッジングをしています。
このErlPortをラップしたgemが erlport-ast_mapping となります。

まとめ

今回のRubyKaigiではErlang,Elixir,アクターモデルなど、並行性に関する言及が多くありました。
その中でも特に印象に残ったErRubyについて紹介しました。
スライドにもありますが、まだまだ実験段階のものなので実用には程遠いですが、面白いアイデアのプロダクトなので、今後もwatchしていきたいと思います。

18
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
15