2020/09/11 今週の気になった bugs.ruby のチケット

内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。

[Bug #15412] OpenStruct error when attribute is called 'method'

  • OpenStruct は次のように要素にアクセスする事ができる
require "ostruct"

o = OpenStruct.new({ hoge: 'foo' })

# hoge の getter メソッドにアクセスできる
p o.hoge
# => "foo"
  • しかし、次のように method を参照しようとするとエラーになる
require "ostruct"

o = OpenStruct.new({ method: 'get' })
# error: `method': wrong number of arguments (given 0, expected 1) (ArgumentError)
o.method
  • これは method がすでに定義済みメソッドなので再定義されない為
  • このチケットではこういうケースに対してどうしようか議論がされている
    • 例えば既存のメソッドと競合する場合は警告を出したりとか既存のメソッドを上書きしていまうとか etc...
  • ちなみに Struct は既存のメソッドを上書きする
p Struct.new(:method).new("hoge").method # => "hoge"
  • また、この影響で次のように標準にメソッドが追加されると既存のコードが壊れてしまう事がある
o = OpenStruct.new

# getter の場合はバージョンによって挙動が異なる
p o.then
# Ruby 2.5 => nil
# Ruby 2.6 => #<Enumerator: #<OpenStruct>:then>

# setter はどのバージョンでも動作する
o.then = :foo
p o.then
# Ruby 2.5 => :foo
# Ruby 2.6 => #<Enumerator: #<OpenStruct then=:foo>:then>
  • 今はこのチケットに対応する PR が投げられてる
  • この PR により以下のような挙動になるっぽい(間違ってたらゴメンネ
    • #[] でアクセスできるようになった
      • measurements = OpenStruct.new("length (in inches)" => 24); measurements[:"length (in inches)"]
    • 既存のメソッドを上書きできる
    • 元のメソッドを参照したい場合はメソッドに ! を付ける
      • OpenStruct.new.class! # => OpenStruct

[Feature #17163] Rename begin

  • Range#begin は getter メソッドで処理は行わないので動詞である begin ではなくて名詞にしようという提案
  • チケットで提案されているのは Range#start
  • Range#endend は動詞であり名詞であるのでこちらは問題ないとの事
  • わたしは使い慣れているのもあってこういうのは気にならないんですが、英語圏の人だとこういうのって気になったりするんですかね?

[Feature #17145] Ractor-aware Object#deep_freeze

  • Object#deep_freeze を追加する提案
  • 背景としては Ractor 間でやりとするオブジェクトは deep frozen されている必要があり、それを補助する機能として提案されている
  • #deep_freeze されているかどうかをどう判定するのかなど議論されている
  • HashArray を要素ごと freeze したいことはあるので機能としてはほしいな〜

[Feature #16150] Add a way to request a frozen string from to_s

merge, fix されたチケット