Rubyで、与えられた文字列をそのままRubyのコードとして解釈して実行する evalメソッドについて説明します。
evalメソッドの使い方
eval メソッドは、Ruby の組み込みカーネルメソッドです。
1 |
eval(評価する式 [,Bindingオブジェクト, ファイル名, 行番号]) |
このうち、第1引数以外は省略可能です。第2引数のBindingオブジェクトとは、そのメソッドや変数が属する「文脈(スコープ)」が保存されているオブジェクトです。
以下より、サンプルコードを元に eval メソッドの使い方について説明します。
eval メソッドを使ったサンプル
例えば、putsメソッドでHello Rubyと表示する場合は、以下のようになります。
1 2 |
eval("puts 'Hello Ruby'") # => Hello Ruby |
第一引数で指定された文字列「"puts 'Hello Ruby'」が実行されていることがわかります。
Binding オブジェクトを指定する
Binding オブジェクトは、理解が難しいですが、次のようにしてみるとわかりやすいでしょう。
1 2 3 4 5 6 7 8 9 10 |
def sample a = 1 binding ##fooの Binding オブジェクトを生成して返す end eval("p a") #=> undefined local variable or method `a' eval("p a", sample) #=> 1 |
トップレベルから eval メソッドで sample メソッドのローカル変数 a を参照しようとしても、 undefined エラーとなります。
ですが、sample メソッドの Binding オブジェクトを第二引数で指定することで、変数 a を参照することができます。
詳しくは、以下のページで説明しているので参照してみてください。
こうした特性を利用すると、プログラムの自由度が飛躍的に高まります。
eval メソッドとメタプログラミング
Rubyの特徴として、プログラムにプログラムを書かせる「メタプログラミング」や、自分好みの言語を作る「DSL(Domain Specific Language)」が容易に実現できることが挙げられます。
evalメソッド やその仲間(eval族と呼ばれます)は、こうしたRubyの上級テクニックを実現するために、欠かせない役割を果たしています。