2021/03/25 今週の気になった bugs.ruby のチケット
内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。
[PR irb #212] Complete require and require_relative
- irb で
require
のファイル名補完をする機能の追加
irb(main):001:0" require "irb/<Tab> # <- Tab を押すとファイル名を補完してくれる
- これは普通に便利そう
[PR irb #204] Add whereami command
irb
にpry
のwhereami
コマンドを追加する PRwhereami
するとbinding.irb
した付近のコードを確認することができる
$ ruby /tmp/a.rb From: /tmp/a.rb @ line 3 : 1: a = 1 2: @b = 2 => 3: binding.irb irb(main)[01:0]> a => 1 irb(main)[02:0]> @b => 2 irb(main)[03:0]> whereami From: /tmp/a.rb @ line 3 : 1: a = 1 2: @b = 2 => 3: binding.irb => nil
- pry の
whereami
コマンド知らなかった - これはめっちゃ便利そう…
[PR irb #203] Implement pry-like ls command
irb
にpry
のls
コマンドを追加する PRls
すると引数オブジェクトのメソッド一覧やインスタンス一覧を出力してくれる
$ irb irb(main):001:0> require "erb" => true irb(main):002:0> ls ERB.new('test') ERB#methods: def_class def_method def_module encoding filename filename= lineno lineno= location= make_compiler result result_with_hash run set_eoutvar src instance variables: @_init @encoding @filename @frozen_string @lineno @src => nil
- これも知らなかった
- めっちゃ便利そう…
[Feature #17411] Allow expressions in pattern matching
- 以下のように
^
を使ってパターンマッチに式をかけるようにする提案
user = { name: "homu", age: 14 } case user # 式を書く場合は ^() を使う in { age: ^(7 + 7) } end
- これが実装されてマージされた :tada:
- 早くパターンマッチ使いたい…
[Bug #17738] Ruby can still freeze ENV
ENV
は普通はfreeze
できないががんばればfreeze
できるという報告
# これは error ENV.freeze # こうすると freeze できる Kernel.instance_method(:freeze).bind(ENV).call() p ENV.frozen? #=> true
- Ruby むずかしい…
[Bug #17735] Hash#transform_keys!
drops non evaluated keys
- 以下のように
Hash#transform_valies!
のブロック内でraise
するとレシーバは変わらない
# transform_values! はレシーバの要素を保持する hash = {a: 1, b: 2, c: 3} a = hash.transform_values! { raise } rescue p hash #=> {:a=>1, :b=>2, :c=>3}
- しかし
Hash#transform_keys!
の場合はレシーバが空になる
# transform_keys! はレシーバの要素が空になる hash = {a: 1, b: 2, c: 3} hash.transform_keys!(){ raise } rescue p hash #=> {}
[Bug #17736] Destructive methods inconsistently handle receiver frozen state
in given block
Array#select!
のブロック内でレシーバをfreeze
するとレシーバが空の配列になる
array = [1, 2, 3, 42] array.select! do array.freeze false end p array #=> []
Array#uniq!
の場合は例外になりレシーバはそのままになる
array = [1, 2, 3, 42, 2, 3] begin array.uniq! do |item| array.freeze item end rescue => err p err #=> #<FrozenError: can't modify frozen Array: [1, 2, 3, 42, 2, 3]> end p array #=> [1, 2, 3, 42, 2, 3]
Array#select!
の方はバグということで修正された
array = [1, 2, 3, 42] # Ruby 3.1.0-dev だとエラー # error: `select!': can't modify frozen Array: [1, 2, 3, 42] (FrozenError) array.select! do array.freeze false end
[Bug #17739] Array#sort! changes the order even if the receiver raises FrozenError in given block
Array#sort!
のブロック内でレシーバをfreeze
すると例外が発生するがソート済みになっているというバグ報告- [Bug #17736] と同じようなバグ
array = [1, 2, 3, 4, 5] begin array.sort! do |a, b| array.freeze if a == 3 1 end rescue => err # 例外が発生する p err #=> #<FrozenError: can't modify frozen Array: [5, 4, 3, 2, 1]> end # 例外が発生してもソート済みになっている p array #=> [5, 4, 3, 2, 1]
- ちなみに
break
した場合はそこまでのソートになっている
array = [1, 2, 3, 4, 5] array.sort! do |a, b| break if a == 3 1 end # 途中までソートされた状態 p array #=> [3, 4, 2, 1, 5]
- これはまだ未修正
[Feature #17743] Show argument types in backtrace
- バックトレースに引数情報も追加する提案
- 例えば以下のようなコードを実行すると
def say_hi(person) puts message(person) end def message(person) "hi: #{person.name}" end say_hi(nil)
- 以下のようなバックトレースが出力される
/tmp/vTaZxJg/70:6:in `message': undefined method `name' for nil:NilClass (NoMethodError) from hi.rb:2:in `say_hi' from hi.rb:9:in `<main>'
- これを以下のようにする提案
hi.rb:6:in `message': undefined method `name' for nil:NilClass (NoMethodError) from hi.rb:2:in `say_hi' called with NilClass from hi.rb:9:in `<main>' called with NilClass
- どのような表記にするのか(クラスだけ?値は必要がない?複数の引数の場合は?)やパフォーマンス的な懸念点がないか議論されている
[Feature #17744] Accumulate Enumerable#tally
results
- 以下のように
Enumerable#tally
に引数を渡してそれに結果を集計していくような提案- 元々は今月の開発者会議で提案されていたっぽい
h = {} [:a,:b,:c].tally(h) [:a,:b,:d].tally(h) # 2個の tally の結果が h に蓄積される p h #=> {:a=>2, :b=>2, :c=>1, :d=>1}
- 便利な気がするけど引数が変更されてしまうのはなんかちょっと気持ち悪い…