技術ブログ

(技術系中心)基本自分用備忘録なので、あくまで参考程度でお願いします。

Rubyのinitializeメソッドの引数の順番の依存を取り除く方法

Rubyのinitializeメソッドは引数の順番に依存している

次の例では、Hogeのinitializeメソッドは次の3つを引数をとります。(hikisuu1,hikisuu2,hikisuu3) デフォルト値はなく、それぞれの引数が必須です。

Class Hoge
  def initialize(hikisuu1, hikisuu2, hikisuu3)
    @hikisuu1 = hikisuu1
    @hikisuu2 = hikisuu2
    @hikisuu3 = hikisuu3
  end
end

ここで、重要なのは引数を正しい順番で渡してあげないといけないことです。 newメッセージの送り手は引数の順番に依存します。 その順番が変わると、そのメッセージの送り手全てに変更を加える必要があります。

Hoge.new(1,2,3)
=> hikisuu1に1が代入
=> hikisuu2に2が代入
=> hikisuu3に3が代入

Hoge.new(3,1,2)
=> hikisuu1に3が代入
=> hikisuu2に1が代入
=> hikisuu3に2が代入

Hoge.new(2,3,1)
=> hikisuu1に2が代入
=> hikisuu2に3が代入
=> hikisuu3に1が代入

Rubyのinitializeメソッドの引数の順番の依存を取り除く方法

で、この固定された引数の順番を取り除く方法を紹介します。 結論から言うと、固定されたパラメーターの代わりにオプションのハッシュを受け取るようにコードを変えればOK。

Class Hoge
  def initialize(arg)
    @hikisuu1 = arg[:hikisuu1]
    @hikisuu2 = arg[:hikisuu2]
    @hikisuu3 = arg[:hikisuu3]
  end
end

※引数にデフォルト値を設定する場合
Class Hoge
  def initialize(arg)
    @hikisuu1 = arg[:hikisuu1] || 40
    @hikisuu2 = arg[:hikisuu2] || 24
    @hikisuu3 = arg[:hikisuu3]
  end
end

argはハッシュであり、入力の全てが含まれます。 initializeメソッドは、このハッシュから必要な引数を取れるようになります。 このテクニックを活用すれば、引数の順番に対する依存を取り除くことができます。

ケース1
Hoge.new(
  :hikisuu1 => 1,
  :hikisuu2 => 2,
  :hikisuu3 => 3
)

=> hikisuu1に1が代入、hikisuu2に2が代入、hikisuu3に3が代入される

ケース2 
Hoge.new(
  :hikisuu1 => 10,
  :hikisuu2 => 11,
  :hikisuu3 => 34
)

=> hikisuu1に10が代入、hikisuu2に11が代入、hikisuu3に34が代入される

キーワード引数で引数の順番の依存を取り除く方法(2019/5/3追記)

Qitaコメントにて、キーワード引数を活用すればより簡単に引数の順番の依存を取り除ける方法を教えていただけたので追記します。

こっちの方が簡単かもですね!

class Hoge
  def initialize(hikisuu1: 40, hikisuu2: 24, hikisuu3: nil)
    @hikisuu1 = hikisuu1
    @hikisuu2 = hikisuu2
    @hikisuu3 = hikisuu3
  end
end
Hoge.new(hikisuu1: 40, hikisuu2: 24, hikisuu3: nil)

=> hikisuu1に40が代入、hikisuu2に24が代入、hikisuu3にnilが代入される

参考文献

オブジェクト指向実践ガイド