MENU閉じる

LAB

RubyプログラムTIPS

研究室プログラムTIPSRuby2010.8.18

コードも渡してみました

以前、アプリが使うバイナリデータをRubyで作る事を書きましたが、
データを作るとなると、定数の値のようにアプリ側とデータ側で共通化したいモノが出てきます。
 
これを別々に定義すると、一方を変更して、他方をそのままにしていた・・・というミスが怖いです。
 
そのため、独立したファイルに定数を定義し、C/C++(アプリ)側とRuby(データ生成)側の両方が参照したり、Ruby側がC/C++のソースコードを参照したりなど、1つの定義で済むようにします。
  

その際、Rubyの「eval」という関数が面白い活躍をしてくれます。
 
evalは、渡された文字列をRubyスクリプトとして評価するという関数です。
スクリプトとして評価されるので、定数の定義はもちろんの事、各種演算なども行ってくれます。
 
これに、RubyはC/C++とほぼ同等の演算子が用意されている
ということを踏まえると下記のような事もできるようになります。
  

C/C++側でインクルードする事を想定し、以下のような内容のファイルがあるとします。

  DEF_ALPHA   = 123,
  DEF_BETA    = 456,
  DEF_GAMMA   = DEF_ALPHA + DEF_BETA,
  DEF_DELTA   = (DEF_GAMMA * 2 + 1) << 4,

そして、ここで定義された内容を、Ruby側でも定数として使えるようにしたいと思います。
 
まずは、evalを使わないで実現する方法を考えてみます。
ぱっと思いつくのは、文字列を1行ずつ解析する方法でしょうか。
 
DEF_ALPHA や DEF_BETA は数値の代入なので簡単ですが、DEF_DELTA となるとちょっと大変です。
さらに複雑になれば尚更ですね。
 
では、evalを使う方法を考えてみましょう。
行末のカンマはRubyの文法上ダメなので、文字列を読み込んだ後で削除します。
あとは、1行ずつevalに渡すだけです。
 
スクリプトとして評価されるので、定義された定数の参照や演算は
インタプリタが処理してくれるという寸法です。
 
実際に試すと、evalを使った方がどのくらい簡単になったかを実感して貰えると思います。

  
普段、C/C++のようなコンパイル型言語を扱っていると、
プログラムを実行する時点でコードを渡すという発想が出てこなくなるかもしれません。
(ちなみに、私はまったく出てきませんでした)
 
でも、別の言語なら簡単に出来てしまいます。
 
言語だけでなく使っているツールやゲーム、考え方など、新しい何かに触れたら、
今まで無理だと思ってたことがあっさり出来るようになるかもしれません。
もしかしたら、想像もしてなかった事が見えてくるかも!?
 
そう考えると、ちょっとワクワクして来ませんか?
 
夏休みも残り少ないですが、是非色々と試してみて下さい。
きっと面白い何かが見つかるんじゃないかなと思います。

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE