やわらかテック

興味のあること。業務を通して得られた発見。個人的に試してみたことをアウトプットしています🍵

OpenStructの存在に気づいた時にはすでに非推奨だった

Rubyを業務で書き始めて3年目になりますが、まだまだ知らないことばかりだなぁと思わされます。
先々週に届いたRubyWeeklyに構造体(struct)について解説している記事が紹介されており、気になったので記事を読んでみるとOpenStructという自分が全く知らない構造体が登場しているではありませんか。

要素(フィールド)を動的に追加・削除することが可能という点でOpenStructは通常の構造体とは異なっています。

通常の構造体

Address = Struct.new(:city)
address = Address.new("gifu")

address.city = "nagoya"
address.postcode = "3333333"
# Main.rb:20:in `<main>': undefined method `postcode=' for #<struct Address city="nagoya"> (NoMethodError)

# address.postcode = "3333333"

OpenStruct

require 'ostruct'

address = OpenStruct.new(city: "gifu")
address.city = "nagoya"
address.postcode = "3333333"
puts address #<OpenStruct city="nagoya", postcode="3333333">

またOpenStructの歴史は古くコミットのログを見てみると20年以上前に遡ります。

* lib/ostruct.rb: documented · ruby/ruby@0425463 · GitHub

中途半端な感じがする

僕はOpenStructのような自由度の高いものが、あまり好きではありません。
ハッシュ(連想配列)が気にならないのは、型の束縛は言語によってあれど自由に使えるデータ構造として広く定着しており、多くの言語で提供されているためです。
しかしOpenStructは構造体のような厳格さはない。とはいえ、ハッシュのような自由さもないため、どっちつかずで中途半端なものに感じてしまいます。 またOpenStructの実装コードを見てみると、内部では値の保持にハッシュ(@table)を使っているようでした。

この事実が尚更、OpenStructの必要性を薄めている気がします。

class OpenStruct
  :
  def initialize(hash=nil)
    if hash
      update_to_values!(hash)
    else
      @table = {}
    end
  end
end

ostruct/lib/ostruct.rb at 69f6661f6219175adc8949ff61ff10b558bc8494 · ruby/ostruct · GitHub

と思ったら非推奨になっていた

なんて偉そうに書いてみたもののOpenStructはRuby3.0から使用が非推奨になったそうです。
よく見てみたらOpenStructクラスを定義しているファイル上部に使用上の注意事項が記載されていました。

# == Caveats
# :
# For all these reasons, consider not using OpenStruct at all.

zenn.dev

通常のハッシュや構造体と比べて遅いというのも、ハッシュをラップしているから当然ですよね。
また組み込みのメソッドを簡単にオーバーライド可能というのもセキュリティリスクがあるため、懸念されているようでした。RuboCopにもOpenStructを使っている箇所を発見したら警告を出力するCopが追加されたそうです。仕事が早いなぁ...。

msp-greg.github.io

最後に

OpenStructについて知った時には「時すでに遅し...」でした。
とはいえ仮にOpenStructが非推奨になっていなかったとしても、自分が使うことはなかったと思います。時代と共に求められるものが変化していくのは当然の流れなので、こうして1つの機能が役目を終えるというのはコミュニティが健全であることの証拠です。

OpenStructについて知るきっかけを与えてくれたのはRubyWeeklyのおかげです。
毎週、木曜日に届くRubyWeeklyにはRubyの最新情報や関連情報がまとめられており、情報のキャッチアップに非常におすすめです。
完全無料なので、興味がある方はぜひ購読をしてみてください。

rubyweekly.com

少しでも「ええな〜」と思ったらはてなスター・はてなブックマーク・シェアを頂けると励みになります。