Ruby で構造体的なデータを表すクラスにはいろいろありますが,その代表格は,やはり組込みクラスの Struct ですよね。
たとえば,猿への給餌計画を表す ApeFeed
クラスはこんなふうに:
ApeFeed = Struct.new(:morning, :evening)
proposed_ape_feed = ApeFeed.new(4, 3)
p proposed_ape_feed.morning # => 4
p proposed_ape_feed.evening # => 3
しかし,どうも私は Struct を多用する気になれないでいます。
理由の一つは,Struct.new
が Struct のインスタンスではなくサブクラスを返す,という謎仕様。
えっと,クラスに new
したらインスタンスを生成して返すでしょ,ふつう。
なぜこんなワケの分からない仕様なのか理解に苦しみます。
もう一つは,上記のようなコードだと,ApeFeed.new(4, 3)
の引数のどっちがどっちかすぐ分かんなくなっちゃうことなんですよね。
やっぱり ApeFeed.new(morning: 4, evening: 3)
と書きたいじゃないですか。
いや,もちろんその手段はあって,
ApeFeed = Struct.new(:morning, :evening, keyword_init: true)
proposed_ape_feed = ApeFeed.new(morning: 4, evening: 3)
p proposed_ape_feed.morning # => 4
p proposed_ape_feed.evening # => 3
のようにすればよろしい,と。
ただ,keyword_init: true
って,ちょっと長すぎないですか?
で,私は keyword_init
てのが覚えられないんですよ。「ナントカ init だっけ?」「頭にアンダースコア付くんだっけ」って。
まあ頻用すれば覚えられると思いますけど。
ここから本題ですが,Ruby 3.2 では上記のようなコードで keyword_init: true
を付けなくてもいけるようになるらしいです。
https://www.ruby-lang.org/en/news/2022/09/09/ruby-3-2-0-preview2-released/
現在,Ruby 3.2 は 3.2.0-preview2 が出ていて,Linux や macOS の人は rbenv で気軽にこの preview2 を試すことができます。
私もこれをインストールしてやってみました:
ApeFeed = Struct.new(:morning, :evening)
proposed_ape_feed = ApeFeed.new(morning: 4, evening: 3)
p proposed_ape_feed.morning # => 4
p proposed_ape_feed.evening # => 3
確かに keyword_init: true
無しでイケてます。
これで Struct のヤな感じが一つ減りました。
ただ,ライブラリー中でこんなふうに書けるのは何年も先ですよねえ。ライブラリーはある程度古い Ruby でも動かないといけないから。
追記 2022-09-26
Struct
やその仲間などについて改めて調べて比較した記事を書きました:
Ruby の構造体的・ハッシュ的データ構造についての考察 (1) - Qiita
反響が無さすぎてちょっぴり寂しい。