【Ruby ことはじめ!?】やらなくても困らないことをやってみる
何の記事??
タイトルの通り、Ruby 関連で「やらなくても特に困らないのに、あえてやってみる」をテーマにちょーっとだけマニアックな話をしていきたいと思います。
Ruby についてプログラミング技法的な部分、明日使えるノウハウ的なことをメインに話すわけではないので読み物としてお楽しみいただければと思います。
目次的には以下の通りです。
- Ruby 自体のソースコードから Ruby をインストールしよう
- Ruby 自体の実装をデバッグしよう
- Ruby の GC の仕組み
それでは見ていきましょう〜!!
Ruby 自体のソースコードから Ruby をインストールしよう
さて、Mac を使っている方は Ruby がそもそも入っています。
Windows の方は、Cygwin を入れるなどして Ruby の開発環境を自分の PC 上に作成するかと思います。
さて、ここであまりやらない方法で Ruby をインストールしてみようと思います。 (一応 Ruby のサイトで紹介はされているので変なやり方ではありません。)
その方法は、Ruby のソースコードからのビルドです。
何の意味があるの??的な質問が飛んできそうですね(笑)
安心してください、意味はあります!!← 古いかw
それは、Ruby 自体の実装を改造することができることにあります。Ruby はオープンソースのプログラミング言語であるために Ruby 自体のプログラムをみることはでき、自分用 Ruby を作るなどの拡張ができるんです。
それでは、早速 Ruby のソースコードを取得してみましょう。
Subversion か git で取得することができます。
■Subversion 編
svn co http://svn.ruby-lang.org/repos/ruby/trunk 任意の名前
■git 編
git clone git://github.com/ruby/ruby.git
これで皆さんのローカルPCに Ruby のプログラムを持ってくることができました。
実際に中身をみてみると C ファイルだらけですね。Ruby は C言語で実装されているため Ruby の拡張機能なんかを作りたい場合は、このCファイルを拡張する必要があります。
それでは実際に使えるようにコンパイル・インストールを行なっていきます。
基本的に普通のプロジェクトインストールの流れと似ていて、
「設定ファイル作成→makeファイル作成→make→インストール」
という流れになります。
大前提ですが、先ほど持ってきたディレクトリに移動し、下記コマンドで設定ファイルを作成します。
autoconf
設定ファイルができたら(上記コマンドが正常に終了したら)make ファイルを作成しましょう。
./configure
それでは make コマンドでコンパイルを行なっていきましょう。
make make check
make check の結果「check succeeded」が出力されれば OK です。
下記コマンドでインストールしていきましょう。
make install
最後にパスを通して完成です!!
export PATH=/usr/local/bin:$PATH
Ruby 自体の実装をデバッグしよう
せっかく Ruby 自体のソースコードを入れたのでどのように動いているかを見てみましょう。
・・・といきたいのですが、それを書き始めると本一冊レベルになるので今回はデバッグの方法を紹介します!
デバッグモードに切り替えるために先ほどの工程で、make ファイルを作成するときに下記に変更してください。
./configure CFLAGS=-g
あとは先ほど同様に make, make install を行なってください。
デバッガには gdb を使用します。
実際に動かしたい Ruby プログラムを作成し、下記コマンドでデバッグしてみてください。(gdb の使い方は今回は主旨とはずれるので割愛します。)
Ruby の実装(Cプログラム)がどう動いているのかがわかります!!
gdb --args ruby ~~.rb
Ruby の GC の仕組み
Ruby の GC のお話です。
さすがに難しく、以下の素敵な記事の要約的な部分があります。お許しください(笑)
まず根本的な問題として GC(Gabage Collection) って何??というと事から解説します。
オブジェクトを作成場合などにコンピュータ上のメモリ領域をそのオブジェクトのために割り当てます。子供ができたので子供部屋を作成してあげるイメージですね。
さて、プログラム中で使わなくなった変数やオブジェクトのためにいつまでもメモリを確保しておくわけにはいきません。いわゆるメモリリークの原因になります。
そこで不要になったオブジェクトを自動で(プログラマが意識せずに)掃除するというのが GC です。GC は Gabage Collection の略なので直訳で「ごみ集め」です。まさに言葉の通りの機能ですね。
それでは Ruby の GC について見ていきましょう。以下のプログラムをご覧ください。
class Node def initialize(val) @value = val end end p Node.new(1) p Node.new(2)
上記コードで Node クラスのインスタンスを作成している(Node.new の部分)時の動きを見ていきます。
実はこれといって何もしていないそうです!!というのも Ruby ではあらかじめ何千ものオブジェクトを作成し、それを freelist という連結リスト上に配置します。
イメージ的には以下の図のようです。
オブジェクトの作成を繰り返すことで
さて、あらかじめ作っていた freelist を使い切りました。
この時、Ruby は Mark and sweep アルゴリズムを用いて汚染オブジェクトをマークします。
さらに stop the world(必殺技みたいww) によってアプリケーションに処理を一時停止し、汚染オブジェクトを掃除(sweep)した結果が下図になります。
freelist に空きができたのでオブジェクトを格納するスペースが生まれましたね!!
このような仕組みでプログラマはあまりメモリを意識しないで Ruby がかけているわけです!!
最後に
さて早速 Ruby のスレッド部分について自分でも拡張してみました。
まだ完成していないため、いつか公開できるようになりたいなと思っています。
なかなか言語自体の実装に興味を持つ人っていないですが、設計思想とか本当にコードを見ているだけでもとても勉強になります。
この記事が、少しでも興味を持つきっかけになれば嬉しいです。
それではまた次回〜〜