LoginSignup
5
4

More than 3 years have passed since last update.

StructとOpenStruct

Posted at

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

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という名前から想像できたので問題なし。

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

  • Struct.newではClassインスタンス(ex. Man)がつくられる => そのクラスからインスタンス(ex. taro)をつくる
    • 最も具体的なオブジェクトを生成するまでに2段階を要する。
    • 普通にクラスを定義している感覚。
  • OpenStruct.newではいきなりOpenStructインスタンスがつくられる
    • 最も具体的なオブジェクトを生成するまでに1段階のみ要する。
    • クラス定義というよりは、ハッシュを生成している感覚。
    • (Hashとの最大の違いは、メソッドをもたせられることかな?たぶん)
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4