Ruby勉強

インターネットの企画職な人がプログラミングを勉強するブログ

Ruby define_methodとclass_eval

# クラスを動的に定義
A = Class.new

# #1
# Aクラスのコンテクストで
# private_methodであるdefine_methodを使用
A.class_eval{
  define_method(:hoge){|a|
    puts a
  }
}
A.new.hoge("hoge") #=> "hoge"

# #2
# Aクラスのコンテクストで
# private_methodであるdefine_methodを使用
A.__send__(:define_method,:fuga) {|a|
  puts a
}
A.new.fuga("fuga") #=> "fuga"

# #3
# 動的に、クラスを定義し、メソッドを定義する方法例
# procは、Kernel#procを使用。受けたブロックをprocに変換して
# __send__に送り、それを__send__はそのままdefine_methodへ送っている
# わかりやすさという点でこうした方が良いか
#  def definer(class_name,method_name,&k)
#   class_name=Object.const_set(class_name.capitalize,Class.new)
#   class_name.__send__(:define_method,method_name,k)
module A
  def definer(class_name,method_name)
    class_name=Object.const_set(class_name.capitalize,Class.new)
    class_name.__send__(:define_method,method_name,proc)
  end
end
class B
  extend A
end

B.definer("C",:hoge) {|a|
  puts a
}
C.new.hoge(1)

こういった臨機応変にクラスやメソッドを動的定義、追加することは、リフレクションプログラミングという。 見通しは悪くなるが柔軟。