読者です 読者をやめる 読者になる 読者になる

futoase

よろしくお願いします。

Rubyの仕組み "Ruby Under a Microscope” を読んだ (あとちょっとCrystalについて)

Rubyの仕組みを読んだ

Rubyの仕組み ”Ruby Under a Microscope”が会社に合ったので、
借りて読んだ。

Rubyのしくみ -Ruby Under a Microscope-

Rubyのしくみ -Ruby Under a Microscope-

CRubyでのRipper.lexを使った字句解析、構文解析についての話(Bisonのお話、 Rippper.sexpによるASTの表示)、
RubyスクリプトRubyインタプリタが解釈し、ASTノードからYARVが解釈できるYARVバイトコードについて
(RubyVM::InstructionSequenceを使う)。
変数はスタックにどのように保存されるか、などが書かれていて、普段意識していない、知らないことだらけだった。
ModuleClassの内部構造(C)はほぼ同じという点などなど。メソッドテーブルの話とか。たくさん知らないことだらけ。
JRubyRubiniusでのRuby処理系実装についても載ってて、それぞれJava, C++なため
Classベースでの実装が可能になっていることによるCRubyとの実装の差とかも。
最終章のGCについては、CRuby 2.1、2.1より前とJRuby, RubiniusでのGC実装が書かれていた。
2.2からGCに関してはインクリメンタルGCサポートがされた、ということで更に進化している。

http://www.infoq.com/jp/news/2015/01/ruby-2.2.0-released

http://www.atdot.net/~ko1/activities/2014_rubyconf_pub.pdf

Crystalは?

読みきったあと、そういえば最近話しに訊くCrystalってどうなのか、と調べてみたら、
Crystalコンパイラでネイティブなコードを吐き出す、という仕組みのようだ。
とりわけ目を引いたのはMacroの存在だった。

http://crystal-lang.org/docs/syntax_and_semantics/macros.html

define_methodclass_evalメソッドを実装していたメタプログラミングのやりかたが、
テンプレートベースで実装可能となるため、安全性が増す印象を受けた。

crystalを試しにインストールして、macro機能を確認してみる。
Mac OS Xであれば、tapでbrewに新しいリポジトリを追加して、インストールすることが可能だった。

http://crystal-lang.org/docs/installation/on_mac_osx_using_homebrew.html

もし他のバイナリが欲しければ、githubから落とせば良い。

https://github.com/manastech/crystal/releases

crystalをインストール後、試しに以下のメソッドを定義してみる。

macro create_method(name, content)
  def {{name.id}}
    puts {{content}}
  end
end

create_method :foo, 1

foo

実行してみると、

> crystal macro1.cr
1

となった。fooメソッドが作らてた。
他にも複雑な、テンプレート的な構文が使える。forなど。

ただ、以下のことができなかった。

class Male
  getter name

  def initialize(@name)
  end
end

class Female
  getter name

  def initialize(@name)
  end
end

bob = Male.new("bob")
charlotte = Female.new("charlotte")

macro create_method(name, content)
  def {{name.id}}
    {% if content.is_a?(Male) %}
      puts "Mr. " + {{content.name}}
    {% else %}
      puts "Ms. " + {{content.name}}
    {% end %}
  end
end

create_method :male, bob
create_method :female, charlotte

male
female

これを実行すると、

undefined macro method Var#name

と、怒られてしまう。

Crystal::ASTNodeの
interpret methodで呼び出せるメソッドが固定されているようだが...

https://github.com/manastech/crystal/blob/aebee589b1ba64f37910d9bbf6b9adf802f7fd8f/src/compiler/crystal/macros/methods.cr#L11

まあ、使い方は何かしらあるはずだけど。軽く触ったぐらいだが。
速度的にCほどではないにせよ、ほぼRubyの文法そのままか、
コードの移植のコストが低い形で移せるようだ。
今後も開発が続くとしたら、Crystalは期待したい処理系だなあと思った。

まとめ

まとめとして、Rubyの仕組みを読んで色々と勉強になった。
Ruby Magazineの読み方、受け取り方について変わっていくのかなあ。

Copyright (c) 2013-2017 Keiji Matsuzaki