🐘
Struct クラスの使い方
Struct クラスとは
構造体クラスと呼ばれる。
Struct.new
をすることでサブクラスが作成される。
作成されたサブクラスでは、メンバ(プロパティ、フィールドとも言う)に対するアクセスメソッドが定義される。
使い方
環境はこちら
> ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-darwin21]
第1引数が文字列のとき
第1引数がクラス名になる。
※クラス名なので大文字にすること。
Struct.new("User", :name, :age)
#=> Struct::User
user = Struct::User.new("名前", "年齢")
user.name
#=> "名前"
user.age
#=> "年齢"
第1引数がシンボルのとき
名前なしのクラスになる。
第1引数からメンバになる。
Struct.new(:name, :age)
=> #<Class:0x000000010c90e9c8>
# 名前を与えないときは clazz_〇〇という変数やメソッドに格納することが多い
clazz_user = Struct.new(:name, :age)
user = clazz_user.new("名前", "年齢")
user.name
#=> "名前"
user.age
#=> "年齢"
ブロックが渡されたとき
Struct.new("User", :name, :age) do
def greeting
puts "俺の名前は#{name}。"
puts "年齢は#{age}歳さ。"
end
end
user = Struct::User.new("ジョン", 20)
user.greeting
#=> 俺の名前はジョン。
#=> 年齢は20歳さ。
クラス定義との違い
同じことをする時に、initialize とか attr_reader の記述をしなくてもいい。
# クラス
class User
attr_reader :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
# struct
Struct.new("User", :name, :age)
あとは他のクラスを継承できない。
他のクラスへの継承はできるっぽい。
Struct.new("Patient", :name, :age)
class Child < Struct::Patient; end
child = Child.new("子供の名前", "子供の年齢")
child.name
#=> "子供の名前"
child.age
#=> "子供の年齢"
どういう時に使える??
最近現場のつよつよエンジニアが、 FormObject 内で attributes をセットしてるのをみて便利だと思った。
class OderForm
attr_accessor :orders
def initialize(params)
@orders = assign_orders_attributes(params[:orders])
end
def save
# 外部の API サーバーへ POST する処理。
end
private
def assign_orders_attributes(attributes)
attributes.map do |attribute|
clazz_order.new(
attribute[:name],
attribute[:value]
)
end
end
def generate_api_params
api_params = {}
api_params[:orders] = []
orders.each do |order|
temp_hash = {}
# Struct に格納されている各オーダーの情報をとりだして、リクエストパラメータを作っている
temp_hash[:name] = order.name
temp_hash[:value] = order.value
api_params[:orders] << temp_hash
end
api_params
end
def clazz_order
Struct.new(:name, :value)
end
end
Discussion