Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

evalで動的にメソッドを追加する(その2)

今回はインスタンスに紐付けるinstance_evalを扱います。

# -*- coding: utf-8 -*-
class EvalTest
  attr_accessor :val_a, :val_b

  def initialize
    @val_a = 10
    @val_b = "test"
  end
  
  private
  def private_method
    ' hello from private_method'
  end
end

使い方

メソッドの追加

et = EvalTest.new
p et.val_a

p et.respond_to?(:new_method) #=> false

et.instance_eval do
  def new_method
    "yes"
  end
end

p et.respond_to?(:new_method) # => true

変数の設定

p et.val_b  # => "test"
et.instance_eval {@val_b = "NC"}
p et.val_b  # => "NC" 

メソッドの呼び出し

通常の方法では読み出せないprivateメソッドを呼び出す事も。

p et.instance_eval{private_method} #=>  hello from private_method

これを応用したのがinstance_eval()を使うとブロック内でメソッドを呼び出せる - Bye Bye Mooreで扱ったような、文字列にアレコレする方法みたいです。

"test".instance_eval{|e| [e.upcase, e.reverse]}
#=> ["TEST", "tset"]