Rubyの構造体(Struct) の使い時とは?


Rubyには、Structという構造体を扱えるクラスが存在します。

Ruby on Railsにおいては、Hashでデータの受け渡しをするケースが多いですが、必要に合わせて構造体を作って置くと効率的に安全にコーデォングを進めることが出来ます。

Book=Struct.new(:name,:price) do #nameとpriceをプロパティとして持つBook構造体の定義を作成
  def withTax
      self.price*1.08 # do構造ブロックを渡すことでメソッドも定義できる
  end
end
book=Book.new('Ultimate Ruby',4500)
book.name # => 'Ultimate Ruby'
book.withTax => 4860

Hashの場合と比較しましょう

hash = {
  name:'Ultimate Ruby',
  price: 4500
}

def hash.withTax
    self[:price]*1.08
end

さて、構造体はHashより安全と呼ばれますがなぜでしょうか?

まずひとつに、「Hashは存在しないキーを返すとnilを返すが、構造体なら即座にエラーになる」ことが挙げられます。

これはフェイルファストの原則に基けば非常に強力です。

第二に、「構造体は受け入れる値をソースコードに明示している」という点が挙げられます。

つまり、それ以外のものが飛んできたらバグだと宣言しているのです。

これは後からコードを読む人の助けになりますし、障害が起きたときの不具合の切り分けを容易にします。

とはいえ、「普通にクラスを作っちゃったほうがいいんじゃない?」という指摘はもっともです。

ですので、

  • 新しいクラスを作るほどでもない構造化データを扱うときには、HashではなくStructを使うようにする
  • Struct::newの戻り値を定数に代入し、その定数をクラスのように扱う

ことができるとより良いコードが書けるのではないでしょうか。