CでRubyを実行する
この例はtagという単純で小さなゲームです。このゲームには2升あります。青升はキーボード上の矢印キーを使って操作しますが赤升はRubyのスクリプトで操作します。動かすためにC
APIを使ってスクリプトがアクセスできる小さなRuby
APIを定義し、全てのフレーム毎にRubyスクリプトで定義されているメソッドを呼び出し2升用のデータをカプセル化するオブジェクトを渡します。
Rubyスクリプトは以下のような見た目をしています。
CのコードはグラフィックにSDL2と入力を使い、ファイルの変更に合わせてAIスクリプトが即座に再読み込みされるようstat()
(あまり可搬性は高くなさそうですが)を使います。以下はtag.c
です。
Makefileは何ということはありません。
RubyでCを実行する
この例は任意精度計算用のGMP
Cライブラリを包むRubyのC拡張です。これは完全な例からはほど遠いものです。整数関数のみを包み、ライブラリの基本的な機能のみを実装しています。またRubyの既存の数値型といい感じに統合することに心を砕いてはいません。もし
本当の 完全な例が欲しければ GMP gemをご確認ください。
全てはGMP::Integer
クラスを定義しているgmp.c
にあります。
extconf.rb
は本当に単純です。
そしてこれで遂に基数62で自分の名前が何になるのかがわかります。
この例ではCにおける全てを試そうとしましたが、実際は必要ではないです(し望ましくもないです)。Cのメソッドの中に(例にあるto_i
や==
のような)単に有象無象のAPI関数を呼ぶだけのものがあるなら、恐らくRubyでメソッドを実装することに比較して数CPUサイクル分しか稼いでいないでしょう。そしてもちろんCを書く時間が増えてRubyを書く時間が減ってしまうツケを払うことになります。😀
拡張を書くときの共通する慣習はCでは拡張の「肝」だけを実装し、残りを通常のRubyスクリプトでやってコンパイルされたライブラリに取り込むことです。
例えばgmp.rb
スクリプトを書いて拡張を著しく単純にできます。