【Ruby】構造体クラスを使いこなしたい。


概要

みなさん。「構造体クラス」使ってますか?
たくさん利用してる人もいれば、聞いた事もない人がいるかと思います。
便利なRubyのクラスなのでぜひ頭の隅にでも置いておいてください!

Sturctとは

Rubyにおける構造体クラス(Struct)は簡易的なクラスのようなものです。
明示的にアクセスメソッドを定義しなくても、構造体クラス外でメンバの参照・更新は可能です。

以下のような場面で使えます。

  • まとまったデータを扱いたいが、クラス定義式を使ってクラスを作るまでもない場合。
  • クラス内で特定のデータのまとまりを表現する場合。

定義方法

以下のように定義することで構造体クラスを使えるようになります。

# Struct.new('構造体クラス名', メンバ)
Struct.new("User", :name, :age)

# 第一引数を省略する事も可能
User = Struct.new(:name, :age)

# クラスのように定義する事も可能(非推奨)
class User < Struct.new(:name, :age)
end

puts Struct::User.new('山田太郎', 25)
#=> #<struct Struct::User name="山田太郎", age=25>

参照や更新は以下のように簡単に行えます。

Struct.new('User', :name, :age)
user = User.new('山田太郎', 25) 

# 参照
puts user.name #=> "山田太郎"

# 更新
user.name = "山田二郎"
puts user.name #=> "山田二郎"

クラス定義式のようにメソッドを設定する事も可能です。

User = Struct.new('User', :name, :age) do
  def introduction
    "私の名前は#{name}です"
  end

  def greet(word)
    word
  end
end

user = User.new('山田太郎', 25)
p user.introduction #=> 私の名前は山田太郎です
p user.greet('こんにちは') #=> こんにちは

注意点

  • 指定されたメンバ数以上の引数を与えるとエラーとなる。
  • 指定されたメンバ数以下のの引数の場合はnilが入る。
  • インスタンスのメンバの値が同じであれば比較した際にtrueを返す。

こういったものがある

OpenStructというRubyの標準ライブラリがあります。
これは要素を動的に追加・削除できる手軽な構造体を提供するクラスです。

使い方

require 'ostruct'

# 構造体を作って動的にpropertyを追加
ostruct = OpenStruct.new
ostruct.name = '山田太郎'
ostruct.age = 25

puts ostruct.name
#=> "山田太郎"

puts ostruct.age
#=> 25

# ハッシュを使用することも可能
ostruct = OpenStruct.new({ name: '山田太郎', age: 25 })

puts ostruct.name
#=> "山田太郎"

puts ostruct.age
#=> 25