2021/03/11 今週の気になった bugs.ruby のチケット
内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。
[Bug #16908] Strange behaviour of Hash#shift when used with default_proc
.
- 以下のように
default_proc
が設定されている状態でHash#shift
を呼ぶといと意図しない値が返ってくるよっていうチケットHash
が空の時にshift
を呼ぶとdefault_proc
の値が返ってくる
hash = Hash.new{|k,v| k[v] = 0} hash.shift # => 0 hash.shift # => [nil, 0]
- 意図としては両方共
[nil, 0]
が返ってきてほしい - もうちょっと詳細に説明するとこんな感じ
hash = Hash.new{|k,v| k[v] = 0} # 空 p hash # => {} # ここは default_proc 値を返す # ここが意図していないというチケット p hash.shift # => 0 # hash,shift 後は中身が入ってる状態になる p hash # => {nil=>0} # ので、これは [nil, 0] を返す p hash.shift # => [nil, 0]
- この挙動は確かに奇妙
- チケットだと
nil
を返すほうがいい、みたいな意見もある
[Feature #17674] Proposal: Method#source_location
or Method#owner
for refined methods
- https://bugs.ruby-lang.org/issues/15504#note-17 からの派生
- https://github.com/AlexWayfer/gorilla_patch/blob/master/lib/gorilla_patch/cover.rb#L8 こんな実装を書いてある場合に
range.method(:cover?)
でsource_location
が取れなくてそれを対応させてほしいっぽい?- Ruby 2.6 だと
refine + using
しててもrange.method(:cover?) # => nil
になってしまう
- Ruby 2.6 だと
- これは Ruby 2.7 だと既に対応済み
# test.rb module Cover refine Range do def cover?(value) return super unless value.is_a?(Range) super(value.first) && super(value.last) end end end using Cover pp (1..10).method(:cover?).source_location # Ruby 2.6 => nil # Ruby 2.7 => ["/test.rb", 4] pp (1..10).method(:cover?).owner # Ruby 2.6 => Range # Ruby 2.7 => #<refinement:Range@Cover>