k-tokitoh

2019-08-03

StructとOpenStruct

似た名前だが意外と挙動が異なるな、と思ったのでメモ。

Struct

# クラスをつくる
> Man = Struct.new(:age, :sex)  # => Man
> Man.class  # => Class

# クラスからインスタンスをつくる
> taro = Man.new(28, :male)  # => #<struct Man age=28, sex=:male>
> taro.class  # => Man

# 定義した属性を利用できる
> taro.age += 1
> taro.age  # => 29

# 定義していない属性は利用できない
> taro.job = :engineer  # NoMethodError: undefined method `job=' for #<struct Man age=28, sex=:male>

OpenStruct

# コアライブラリではなく標準ライブラリ
> require 'ostruct'

# newするとシンプルにOpenClassインスタンスが返ってくる
> taro = OpenStruct.new({age: 28, sex: :male})  # => #<OpenStruct age=28, sex=:male>
> taro.class  # => OpenStruct

# 定義した属性を利用できる
> taro.age += 1
> taro.age  # => 28

# 定義していなかった属性も利用できる
> taro.job = :engineer  # => :engineer
> taro.job  # => :engineer

違い

「最初に定義してない属性を利用できる/できない」というのは Struct/OpenStruct という名前から想像できたので問題なし。

意外だったのは以下の違い。