Ruby で、Object#initialize の引数をそのままインスタンス変数とする方法。
を、ちょっと考えてみた。
class Object def make_instance_variables (_binding) eval(<<'EOC', _binding) local_variables.each do |lv_name| instance_variable_set("@#{lv_name}", eval(lv_name)) end EOC end end # 問題ないパターン class Neko def initialize (hige, tume, sippo = 1) make_instance_variables(binding) end end p Neko.new(20, 18) #=> #<Neko:0x10010710 @tume=18, @hige=20, @sippo=1> p Neko.new(20, 18, 2) #=> #<Neko:0x7ff4e1a4 @tume=18, @hige=20, @sippo=2> # 問題あるパターン class Cat bug = 'noooooo' define_method(:initialize) do |hige, tume, shippo| make_instance_variables(binding) end end p Cat.new(20, 18, 1) #=> #<Cat:0x7ff4dd1c @tume=18, @shippo=1, @hige=20, @bug="noooooo"> # @bug がセットされてしまっている!
問題もあるけど(make_instance_variablesの前にローカル変数を作っちゃ駄目とか)、楽ではある。
下のエントリをみて、思いついた。
initialize に渡された値を自動的にインスタンス変数にするを読んで。
ちょっと主旨が違うような気もしますが、書いてみました(1)。
inspect を使うと、特定のオブジェクトしか使えないのが厳しいと思う。
21:46
ヒアドキュメントのとこを少し書き換え。