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.
通常のハッシュや構造体と比べて遅いというのも、ハッシュをラップしているから当然ですよね。
また組み込みのメソッドを簡単にオーバーライド可能というのもセキュリティリスクがあるため、懸念されているようでした。RuboCopにもOpenStruct
を使っている箇所を発見したら警告を出力するCopが追加されたそうです。仕事が早いなぁ...。
最後に
OpenStruct
について知った時には「時すでに遅し...」でした。
とはいえ仮にOpenStruct
が非推奨になっていなかったとしても、自分が使うことはなかったと思います。時代と共に求められるものが変化していくのは当然の流れなので、こうして1つの機能が役目を終えるというのはコミュニティが健全であることの証拠です。
OpenStruct
について知るきっかけを与えてくれたのはRubyWeeklyのおかげです。
毎週、木曜日に届くRubyWeeklyにはRubyの最新情報や関連情報がまとめられており、情報のキャッチアップに非常におすすめです。
完全無料なので、興味がある方はぜひ購読をしてみてください。
少しでも「ええな〜」と思ったらはてなスター・はてなブックマーク・シェアを頂けると励みになります。