【初心者必見!】Ruby evalを理解し活用するための4つのTips

50種類以上のIT教材を無料で使える!
0円から学習できるオンラインITスクール「侍テラコヤ」
→さっそく登録する

こんにちは! フリーエンジニアの長瀬です。

みなさんはevalを使っていますか?

evalを使えば、evalに渡した文字をRubyプログラムとして実行させることができます。

この記事では、rubyのevalについて

・evalの使い方
・Bidingオブジェクトの指定

という基本的な内容から、

・instance_evalの使い方
・class_evalの使い方
・module_evalの使い方

といった応用的な内容についても解説していきます。

evalとは

evalとは何かを一言で説明すると「引数として与えた文字列をRubyプログラムとして実行するメソッド」です。

引数として与えた文字列を評価することができ、実行する文のエラーチェックに使うことができるので、異常発生を検知するときに使えます。


【何から学べばいいかわからない…そんな悩みを解決します!】

完全無料ですぐわかる「プログラミング学習プラン診断」

・適性にあわせて学習プランを診断
・完全無料で気軽に診断できる
・学習の悩みもまるっと解決

さっそく診断してみる

基本的なevalの使い方

evalの使い方

evalの基本的な使い方としては下記のように評価する式を引数として与えるだけです。

eval("puts 'Hello, everyone !'")

正式な構文は以下のようになっています。

eval(expr [,bindingObj, fname, fileno])

指定が必須なのは第1引数のみです。それ以外の引数指定は任意です。

第3引数fname, 第4引数filenoが与えられた場合、ファイル名fnameの行番号filenoに評価する式exprが書かれているかのように見せることができます。第2引数に指定するBindingオブジェクトは次の章で説明します。

例えば、スタックトレースに表示されるファイル名やソースファイルの行番号を自由に変更できます。

下記はサンプルコードです。sample.rbの10行目に「raise RuntimeError」が書かれているかのように見せることができます

eval('raise RuntimeError', binding, 'sample.rb', 10)
# sample.rb:10: RuntimeError (RuntimeError)

Bindingオブジェクトの指定

evalメソッドの第2引数には「Bindingオブジェクト」を指定することができます。

変数やメソッドにはそれらが有効な範囲(スコープ)があります。その定義されたスコープを表すオブジェクトがBindingオブジェクトです。

例えば、あるメソッド内で定義された変数をそのメソッドの外部から使用したいときに指定します。

下記のサンプルコードを使いながら、Bindingオブジェクトについて説明します。

def bindSample
hoge = 100
binding # Bindingオブジェクトの生成
end

eval("p hoge", bindSample)

[実行結果]

100

bindSampleメソッド内において、ローカル変数hogeを定義しています。

またbindingメソッドを実行することにより、bindSampleメソッドのBindingオブジェクトを生成して返します。

だからこそ、bindSampleメソッドの外部からローカル変数hogeを参照することができるわけです。

なので、たとえば以下のように、eval内でローカル変数を定義した場合evalで参照することができず、エラーを返します。

eval("hogehoge = 'this is hoge'")
eval("p hogehoge")

[実行結果]

# undefined local variable or method `hoge'

ですが、すでに定義されている変数についてはevalから呼び出したり値を代入したりできます。

hogehoge = "this is hogehoge."
eval("p hogehoge")
eval("hogehoge = 'changed'")
eval("p hogehoge")

[実行結果]

"this is hogehoge."
"changed"

eval応用編

instance_evalの使い方

instance_evalメソッドは、渡されたブロックを実行するものです。以下がサンプルコードです。

class InstanceEvalSample
def initialize
@name = "hoge"
end
end

x = InstanceEvalSample.new
p x.instance_eval { @name }

[実行結果]

"hoge"

このように、インスタンス変数nameをブロック内から参照する事ができます

class_evalの使い方

class_evalメソッドを使うと、ブロックをあたかもクラス定義やモジュール定義の中のコードであるかのように実行することができます。ブロックの戻り値がメソッドの戻り値となります。

class ClassEvalSample; end
ClassEvalSample.class_eval { def hello; "Hello, everyone !"; end }

puts ClassEvalSample.new.hello

[実行結果]

 "Hello, everyone !"

helloメソッドは、ClassEvalSampleクラスの中で定義していないにも関わらず、その中で定義しているかのように実行できます

module_evalの使い方

module_evalはclass_evalのエイリアス(名前は違うけど、機能は同じ)です。

なので、class_evalで紹介したサンプルコードをそのままmodule_evalに置き換えることができます。

class ClassEvalSample; end
ClassEvalSample.module_eval { def hello; "Hello, everyone !"; end }

puts ClassEvalSample.new.hello

[実行結果]

 "Hello, everyone !"

【なかなかエラーが解決できない…そんな悩みを解決します!】

登録無料で始められるプログラミングスクール「侍テラコヤ」

・回答率100%のQ&A掲示板でエラーを解決!
現役エンジニアとのオンライン相談で悩みを解決!
・50種類以上の教材で複数言語を習得!

侍テラコヤについて詳しく見る

まとめ

今回はevalの基本とその使い方について説明したのに加え、Bindingオブジェクトを指定する場合の使い方についても説明しました。

また、応用例としてinstance_evalclass_evalメソッド、module_evalについても紹介しました。evalと類似したメソッドでもありますので、evalの基本を理解した上で、上手く活用していきましょう!

プログラミング学習中、
誰かへ相談したいことはありませんか?

SAMURAI TERAKOYA

プログラミングはエラーの連続。作業を進めるなかで誰かに教えてほしい場面は多いですよね。

そんな悩みを解決できるのが、侍テラコヤです。登録無料で始められて、現役エンジニアとオンラインで相談できるほか、回答率100%のQA掲示版でプログラミングに関する悩みを解決します!

気になる方はぜひ詳細をご覧ください。

→侍テラコヤの詳細をみる

Unityを使ったiOSアプリのリリース、フリマサイト運営の経験があります。

経験した言語はC、C#、Javascript、R、Python、Ruby、PHPなど

言語が好きで、英語や中国、ドイツ語を勉強しました。
将来的には海外で生活したいです。

現在はRuby on Rails5やCocos2dxの勉強を主にしています。

ライターとしては
できるだけ初心者にわかりやすい文章になるように心がけています。

趣味は語学、読書です。

あなたの目的に合わせた
SAMURAI ENGINEERの運営サービス

SAMURAI ENGINEER Pro

未経験でも挫折しないプログラミングスクール

詳細はこちら

SAMURAI TERAKOYA

日本最大級のサブスク型オンラインITスクール

詳細はこちら

SAMURAI ENGINEER Freelance

「一人で稼げる」スキルを身につける

詳細はこちら
Close