メソッドの引数を同名のインスタンス変数に自動的に引き渡すメソッド

http://d.hatena.ne.jp/rubyco/20060403/argsより。

id:rubycoさんはnameとvalueを別々に取っていたけど、Hashでとった方が個人的には見た目が良いと思う。

  make_instance_variables(:name => "walf443", :age => 30)

みたいに。

ちなみにmake_instance_variablesという名前はどうかと個人的に思っていて、attr_accessorとかもインスタンス変数を作ってるじゃないかとか思ったりもします。set_value_of_instance_variablesとかいう名前が適切ではないかと。

initializeを拡張すると、

class Object
  def initialize(hash =nil, *args)
    set_value_of_instance_variables(hash)
    initialize_after(*args)
    ...
  end
  
  def initialize_after(*args)
  end
  private :initialize_after, 
end

とかいった感じにして自動的にインスタンス変数を生成しない処理はinitialize_afterに書くようにすると、

  • インスタンス変数の初期化を行なわず、何らかの処理をコンストラクタで行なわせたい場合は普通にinitializeをオーバーロード。
  • インスタンス変数の初期化のみを行なう場合は、何も定義せずnewメソッドにハッシュを渡せばよい
  • インスタンス変数を初期化し、何らかの処理を行ないたい場合は、initialize_afterメソッドをオーバーロード

といった感じに出来そう。ただ例外を起こしたりするのはちょっとムズそう。

この問題に関しては、

  def initialize(@name, @age, value)
    @value = value / 2
  end

という風にinitalizeの定義の引数にインスタンス変数を指定すると自動的に"@name = name"を行なってくれるといった構文がRubyに実装されないと厳しいような気もします。これをいちいち書くコストの方が素直に書くコストよりも高いので。

これぐらいはなくても良いかなと思ったりしたけど、メソッドの引数をそのまま同じ名前のインスタンス変数につっこむ処理はよくやるので言語レベルでサポートがあると確かにうれしいかもしれない。