2020/11/14 今週の気になった bugs.ruby のチケット
内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。
Pattern matching is no longer experimental
- bugs.ruby ではなくて commit
- パターンマッチが experimental ではなくなった
- 右代入は experimental になるので注意
# no warning case { name: "homu", age: 14 } in { name:, age: } end # warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby! { name: "homu", age: 14 } => { name:, age: }
[Feature #17176] GC.auto_compact / GC.auto_compact=(flag)
GC.auto_compact=
GC.auto_compact
を追加する提案GC.auto_compact = true
にすることで GC 中に自動でGC.compact
を呼び出す- よくわからないので詳細はチケットとか読んでね
[Feature #17294] Feature: Allow method chaining with Pathname#mkpath Pathname#rmtree
Pathname#mkpath
の戻り値をレシーバにしたいという提案Pathname#mkpath
はパスのディレクトリを生成するメソッド- https://docs.ruby-lang.org/ja/latest/method/Pathname/i/mkpath.html
Pathname
のインスタンスを生成しつつ#mkpath
を呼び出す場合、次のように#tap
する必要がある
# Pathname のインスタンスを生成しつつ mkpath でディレクトリも作成したい # #mkpath の戻り値は nil なので tap を経由する必要がある path = Pathname.new("/tmp/new").tap(&:mkpath)
Pathname#mkpath
の戻り値をレシーバにすることで次のようにかける
path = Pathname.new("/tmp/new").mkpath
- 戻り値が
nil
からPathname
に変わるが依存してるコードはなさそうらしい
[Feature #17312] New methods in Enumerable and Enumerator::Lazy: flatten, product, compact
Enumerator::Lazy
に#compact
#product
#flatten
を追加する提案- あると便利そう
[Feature #17314] Provide a way to declare visibility of attributes defined by attr* methods in a single expression
- 以下の2つの変更を提案するチケット
attr_xxx
の戻り値を引数の名前の配列にする提案
attr_reader :id, :name, :age # 今 => nil # 提案 => [:id, :name, :age]
public/protected/private
の引数に配列を渡せるようにする提案
# 提案 private [:id, :name, :age]
- この2つを取り入れると以下のように
private
+attr_xxx
を組み合わせる事ができる
class Foo private attr_accessor :foo, :bar end
# 独自のラッパーメソッドを介したりとか class Module def traceable(names) # ... names end end class Foo traceable attr_accessor :foo # it can be mixed with public/protected/private too protected traceable attr_accessor :bar end
- この手の提案は定期的に出てきてて以下のチケットとかだと
attr_xxx
の戻り値を変えてprivate *attr_accessor :foo, :bar
にかけるような提案とかされている
[Feature #17316] On memoization
- Ruby でメモ化する場合、以下のようなコードを書く場合が多い
@foo ||= some_heavy_calculation(...)
- しかし、厳密には以下のように『インスタンス変数が定義されているかどうか』で判定する必要がある
unless instance_variable_defined?(:foo) @foo = some_heavy_calculation(...) end
- こういうコードは冗長であまり書きたくないのでもっと簡略化して書きたいという提案
- 例えば以下のように
#instance_variable_set
でブロックを受け取るようにしたりとか
instance_variable_set(:foo){ some_heavy_calculation(...) }
- もしくは
#memoize
みたいなヘルパメソッドを定義するとか
memoize(:foo){ some_heavy_calculation(...) }
- 機能としては欲しいんだけど、どういうような書き方にするのかは無限にむずかしそう…
[PR #3740] Speed up ivar set
aaron@whiteclaw ~/g/ruby (init-ivars)> ruby -v test.rb ruby 3.0.0dev (2020-11-05T19:13:04Z master ab5f2fa4fb) [x86_64-linux] Warming up -------------------------------------- init 523.589k i/100ms Calculating ------------------------------------- init 5.281M (± 0.4%) i/s - 26.703M in 5.056507s aaron@whiteclaw ~/g/ruby (init-ivars)> ./ruby -v test.rb ruby 3.0.0dev (2020-11-06T18:37:08Z init-ivars 014059c3cb) [x86_64-linux] Warming up -------------------------------------- init 547.661k i/100ms Calculating ------------------------------------- init 5.444M (± 0.4%) i/s - 27.383M in 5.030236s aaron@whiteclaw ~/g/ruby (init-ivars)> cat test.rb require "benchmark/ips" class Foo def initialize @a = nil @b = nil @c = nil @d = nil end end Benchmark.ips do |x| x.report("init") { Foo.new } end
[Feature #17322] Deprecate Random::DEFAULT
and introduce Random.default()
method to provide Ractor-supported default random generator
- デフォルトの疑似乱数生成器を返す
Random::DEFAULT
という定数がある - これはスレッドセーフではないため Ractor ごとに疑似乱数生成器が参照できないぽい
- 複数の Ractor から参照するとエラーになる
- 複数の Ractor で利用できるように
Random.default()
というメソッドを新しく追加する提案 - それに伴い
Random::DEFAULT
は Deprecate にする- なので Ractor ないでは
Random::DEFAULT
はしないようにする
- なので Ractor ないでは
Thread#[]
みたいに Ractor ごとの固有の変数を定義するようにしてはどうか、とコメントがある- 例えば
Ractor.current[:DEFAULT_RANDOM]
みたいな - https://bugs.ruby-lang.org/issues/17322#note-3
- 例えば
[Feature #17315] Hash #transform
- Hash の要素を変更して Hash を返す
Hash#transform
メソッドの提案
h = {'name' => 'dominic ', 'email' => 'dominic.mail.com '} # キーを String から Symbol に変換する h.transform!{|k,v| [k.to_sym, v.strip]} h # => {name: 'dominic', email: 'dominic.mail.com'}
Hash#map
だと Hash ではなくて Array を返すので Hash を返すメソッドはほしい- 一応、副作用がない版は
Hash#to_h
でも代用可能
h = {'name' => 'dominic ', 'email' => 'dominic.mail.com '} # キーを String から Symbol に変換する p h.to_h { |k,v| [k.to_sym, v.strip] } # => {:name=>"dominic", :email=>"dominic.mail.com"} # レシーバは元のまま p h # => {"name"=>"dominic ", "email"=>"dominic.mail.com "}
- なるほどね?
merge, fix されたチケット
- [[PR #3740] Speed up ivar set])(https://github.com/ruby/ruby/pull/3740)
- インスタンス変数の設定のパフォーマンスアップ