内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。
[PR irb #202] process multi-line pastes as a single entity
- 現行の
irbだと以下のようなコードをペーストするとエラーになる
class A def a; self; end def b; true; end end a = A.new a .a .b
irb(main):001:1* class A
irb(main):002:1* def a; self; end
irb(main):003:1* def b; true; end
irb(main):004:0> end
= > :b
irb(main):005:0>
irb(main):006:0> a = A.new
= > #<A:0x00005588503197b8>
irb(main):007:0>
irb(main):008:0> a
= > #<A:0x00005588503197b8>
irb(main):009:0> .a
/home/worker/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.4/lib/irb/workspace.rb:116:in `eval': (irb):9: syntax error, unexpected '.' (SyntaxError)
from /home/worker/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.4/exe/irb:11:in `<top (required)>'
from /home/worker/.rbenv/versions/3.0.0/bin/irb:23:in `load'
from /home/worker/.rbenv/versions/3.0.0/bin/irb:23:in `<main>'
irb(main):010:0> .b
- これはペーストしたタイミングで Ruby のコードが逐次的に評価され
.aを呼び出した時にエラーになってしまっているため- 先に
aのコードが評価され
- 先に
- これを回避するためにペーストして『最後に』コードを評価するようにする PR
- 個人的には落とし所としてはいいとは思う
[Bug #17571] prependしたArray#[] が反映されない
- 以下のように
Arrayにprependしてる#[]が呼び出されないことがある
module TestMod def [](*) :called end end Array.prepend TestMod # これは Array#[] が呼ばれる p [1, 2, 3][1] # => 2 # これは TestMod#[] が呼ばれる p [1, 2, 3][] # => :called # Method オブジェクトは TestMod を指している p [1, 2, 3].method(:[]) # => #<Method: Array(TestMod)#[](*) /tmp/vud3mdg/27:2>
- これはおそらく
Array#[]を事前にメソッドキャッシュしておりそちらを優先して呼び出しているのが原因ぽい?- なので
prependしているメソッドは呼ばれなくなっている - 引数がない場合は
Array#[]とシグネチャが異なるのでキャッシュされたメソッドではなくてprependされたメソッドを呼び出しているので意図する挙動になっているみたい?
- なので
- これは Ruby 2.7 では問題なくて Ruby 3.0 から問題になっている
- Ruby 3.0 に上げるタイミングでなにか壊れるかもしれないので注意したい
- 原因っぽいコミット(と PR)
[Bug #17725] Prepend breaks ability to override optimized methods
- 以下のように
String.prependするとString#+が上書きされたりされなかったりする
# これは上書きされる class String def + other 'blah blah' end end p 'a' + 'b' # => "blah blah"
# これは上書きされない String.prepend(Module.new) class String def + other 'blah blah' end end p 'a' + 'b' # => "ab"
[Bug #16996] Hash should avoid doing unnecessary rehash
Hash#dupよりもHash#mergeの方が高速だというチケット- 3.5倍早いと書かれている
- これは
Hash#dupは内部で再ハッシュを行っているがHash#mergeは行っていないのでその差になる - Ruby なにもわからない
Hash#replace/dup/initialize_copyで再ハッシュを行わないようにする PR- 開発者会議でも承認されたっぽいのでマージされそう
- ちなみに
hash.selectよりもhash.merge.select!のほうが高速らしいHash#select/rejectで再ハッシュしないようにする PR- https://github.com/ruby/ruby/pull/4273
[Bug #17719] Irregular evaluation order in hash literals
Hashリテラルでキーが重複している場合に以下のような評価順になる
# 1個目と2個目の foo の要素が先に評価される $ ruby -e '{foo:p(1), bar:p(2), foo:p(3)}' -e:1: warning: key :foo is duplicated and overwritten on line 1 1 3 2
- これはバグのようなので修正するチケット
- 以下のような問題もあるしもうエラーにしちゃっていいんじゃないかなあ…。