rubyのinstance_evalメソッド

2022.06.30

instance_evalメソッドとは

オブジェクトのコンテキストで文字列 expr またはオブジェクト自身をブロックパラメータとするブロックを評価してその結果を返します。 文字列 expr やブロック中でメソッドを定義すればそのオブジェクトの特異メソッドが定義されます。

Ruby リファレンス3.1

ブロックを評価(実行)できる。そしてオブジェクトの中に特異メソッドを定義できる。

特異メソッドとは・・定義されたオブジェクトだけが持っている固有のメソッド。

特徴

動的にインスタンス変数やメソッド(特異メソッド)を追加できる。

class Hoge
 def initialize(num)
  @x = num
 end
end
hoge = Hoge.new(1)
p hoge

hoge.instance_eval{@y = 2}
p hoge

#=> <Foo:0x00007ff1299234f8 @x=1>
#=> <Foo:0x00007fd81a897b10 @x=1, @y=2>
class Hoge
 def initialize(num)
  @x = num
 end
end
hoge = Hoge.new(1)
hoge.a
#=> undefined method `a' for #<Foo:0x00007f92679272e0> (NoMethodError)

hoge.instance_eval{
 def a
  p "メソッドa"
 end
}
hoge.a <- #特異メソッド
#=> "メソッドa"

クラス外からプライベートメソッドにアクセスできる。

class Hoge
 private
 def priv_method
  p "プライベート"
 end
end
hoge = Hoge.new
hoge.priv_method
#=> private method `pr_mtd' called for #<Foo:> (NoMethodError) 

hoge.instance_eval{priv_method}
#=> "プライベート"

evalとの違い

evalにはオブジェクトに対して何かをすることはないが、instance_evalはオブジェクトに対して処理を追加したりする。

  • eval・・rubyプログラムを文字列で渡せる。rubyの処理を文字列で渡したい場合に使える。
  • instance_eval・・オブジェクト1つに対して特異メソッドや変数定義ができる。あるクラスの初期値を変更して処理を行いたい時に使えそう。

まとめ

instance_evalは定義したオブジェクトに対してのみ使うものになる。メソッドを追加したい時や変数の追加、編集などができる。プライベートメソッドにもアクセス可能。

定義したオブジェクトに対して動的にメソッドや変数を定義できるのがinstance_evalメソッド。