13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

turboruby のご紹介

Posted at

はじめに

わたしは、日頃は Ruby でお仕事をしていて、ここ 1 年ぐらい Rust を勉強しだし、最近では Rust of Us という有志の勉強会をやっています。
この AdventCalender に登録した時点では、Rust でわたしが作りだしたライブラリについて書くつもりでした。しかし、先日の RubyKaigi で発表のあった turboruby が、かなり面白かったのでその紹介をさせていただきます。

turboruby とは

turboruby とは、TILDE という会社によって作られたものです。

TILDE は、Rust Core team の wycats 等がいます。
wycats は各所で Rust の発表を行なっており、本の貸し借りで Rust の Ownership を説明するスライド を見たことがある人もいるでしょう。

彼の働く TILDE では、Ruby on Rails を使ってプロダクトをつくっており、彼の過去の発表では Ruby と Rust を連携させるもの もありました。
このときの発表では、FFI を使って Ruby から Rust のプログラムを呼んでいました。

しかし、今回の RubyKaigi での発表 では、今までの FFI を使っていたところを turboruby というライブラリを使うようになりました。この turboruby により、Ruby でRust のコードの文字列を返すメソッドを記述することで、Ruby の拡張ライブラリを Rust で記述できるようになります。

どうやって動かすの

turboruby のリポジトリにある README は、bundler によって生成されたままの README なので、情報がないです。そこで、integration_spec.rb を参考、String クラスに hello と返すだけのメソッドを追加するものを作ってみました。

リポジトリに含まれている、run.sh がコマンドの流れ、compile.sh が turboruby のコードをコンパイルするためのスクリプトになります。

まず lib ディレクトリには、src というディレクトリを用意して、その中に trb ファイルを記述します。また、lib ディレクトリには gemspec ファイルも用意しておきます。今回の trb ファイルは、このようになっています。

class String
  def hello
    <<-RUST
      println!("hello");
    RUST
  end
end

このリポジトリのトップで、bundle exec ruby compile.rb lib out とすると、out ディレクトリ内にコンパイルされた Rust のコード類が生成されます。実行後の out ディレクトリの構成は以下のようになります。

$ ls -lR out
total 32
-rw-r--r--  1 takkanm  staff  350 12 16 20:05 Cargo.toml
-rw-r--r--  1 takkanm  staff  168 12 16 20:05 extconf.rb
-rw-r--r--  1 takkanm  staff  467 12 16 20:05 hello.c
-rw-r--r--  1 takkanm  staff  463 12 16 20:05 hello.gemspec
drwxr-xr-x  3 takkanm  staff  102 12 16 20:05 src/

out/src:
total 8
-rw-r--r--  1 takkanm  staff  305 12 16 20:05 lib.rs

では生成された、lib.rs の中身を見てみましょう。

extern crate libc;
extern crate ffi_buf;

use ffi_buf::Buf;

trait RubyString {
    fn trb_hello(&self);
}

impl<'a> RubyString for &'a str {
    fn trb_hello(&self) {
        println!("hello");
    }
}

#[no_mangle]
pub extern "C" fn trb_string_hello(rb_self: Buf) {
    rb_self.as_slice().trb_hello()
}

RubyString の中に trb_hello というメソッドができて、 'hello' と表示されるようになっているのがわかります。

この後、run.sh に書かれている手順で、crate の build 、make を行なうと hello.bundle(mac の場合)ができ、その共有ライブラリを Ruby に読み込ませて実行できることがわかります。

最後に

今回は単純に文字を表示するメソッドを追加しただけですが、turboruby のリポジトリにある例のように、Ruby のオブジェクトを Rust 側に渡して値を返すということもできます。

turboruby は、ソースを読むとまだまだ実験的なライブラリで、機能が足りてないことがわかります。
しかし、これが成長すれば普段 Rails で仕事しているような私にはとっても恩恵があるような気がしており、とても楽しみです。

13
13
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
13
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?