ブログ記事 からの転載です。
入りました。
元々はパターンマッチの 1行 in を利用して分割代入を行えるような機能が Ruby 2.7 で実験的に入っていました。
# Ruby 2.7 で動くコード
p RUBY_DESCRIPTION
# => "ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]"
data = { name: "homu", age: 14 }
# 1行 in を使うと分割代入を行うような事ができてた
data in { name:, age: }
p name # => "homu"
p age # => 14
しかし、Ruby 3.0 でパターンマッチが正式に導入されるタイミングで1行 in は一旦削除される予定になっていました。
分割代入はかなり便利な機能なので欲しかったので削除されるのは残念だなあ、と思っていたんですが1行 in が削除される代わりに Ruby 3.0 の右代入で分割代入が実装されました。
これにより1行 in で行えたような分割代入が右代入でできるようになりました。
p RUBY_DESCRIPTION
# => "ruby 3.0.0dev (2020-10-26T09:00:24Z master 52c630da00) [x86_64-linux]"
data = { name: "homu", age: 14 }
data => { name:, age: }
p name # => "homu"
p age # => 14
ちなみに分割代入と言っていますがあくまでもパターンマッチの変数キャプチャ機能になるので以下のように使えることもできます。
data = { name: "homu", age: 14 }
# 一部だけ代入できる
data => { age: }
p age # => 14
# Struct でもキャプチャできる
data = Struct.new(:name, :age).new("mami", 15)
data => { name: }
p name # => "mami"
# マッチしなかった場合に raise NoMatchingPatternError が発生する
data => { name: Integer }
元々 1行 in は if
の条件式として使いたい経緯があったんですが、最終的にはそういう用途で利用できなくなり逆に分割代入という微妙に意味が異なる機能になってしまいました。
それが右代入で実装されたことでより意味が違い機能になって個人的にはかなりよくなったと思います。
逆に 1行 in では条件式で使えるように true / false
を使えるような機能になってほしいですねえ。
ひとまずこれで右代入の使いみちができましたね!!
ところで左代入でも分割代入するような方向にはなるんでしょうか。