2020/09/04 今週の気になった bugs.ruby
内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
Version number bumped to 3.0.0 from 2.8.0 (tentative)
- 開発版の Ruby が 2.8 から 3.0 になった、めでたい
- これでほぼほぼ 3.0 がリリースされる事が確定に
[Feature #16994] Sets: shorthand for frozen sets of symbols / strings
- %記法で
freeze
されたSet
を記述できるように追加する提案
%ws{hello world} # => Set['hello', 'world'].freeze %is{hello world} # => Set[:hello, :world].freeze
- 例えば
%ws{foo bar}.include?(str)
みたいなコードで利用できるSet
のほうが高速なので便利そう
[Bug #17017] Range#max & Range#minmax incorrectly use Float end as max
Range#max
とRange#minmax
のその後- 元々は以下のようになるように修正された
# to_a したときと挙動を合わせたい (1..3.1).to_a.max # => 3 (1..3.1).to_a.minmax # =< [1, 3] (1..3.1).max # Ruby 2.7 # => 3.1 # 修正後 # => 3 (1..3.1).minmax == [1, 3.1] # Ruby 2.7 # => [1, 3.1] # 修正後 # => [1, 3]
- しかし、上記の対応で以下のようなコードがエラーになってしまった
p (42..Float::INFINITY).max # Ruby 2.7 # => Infinity # 修正後 # error: `floor': Infinity (FloatDomainError)
- 上記の挙動だと既存の gem に影響があったため、以下のように修正された
p (42..Float::INFINITY).max # Ruby 2.7 # => Infinity # 修正後 # => Infinity
- ここまでが今までの話
- このチケットだが、最終的にはまつもとさんの意向により Revert された
- 意図としては
Range
の役割としては『Enumerable
としての機能』と『両端のデータを持つオブジェクトとしての機能』の 2パターンあり、今回の#max
#minmax
は『両端のデータを返す』という意図があるということだった - なので
(1..3.5).max
は終端の3.5
を返すのが意図する動作になる、ということらしい
[Feature #14394] Class.descendants
.ancestors
はレシーバが『継承してる』クラス/モジュールの一覧を返す.descendants
はレシーバが『継承されている』クラス/モジュールの一覧を返す
module A end module B include A end module C include B end A.descendants #=> [A, C, B] B.descendants #=> [B, C] C.descendants #=> [C]
class A end class B < A end class C < B end A.descendants #=> [A, B, C] B.descendants #=> [B, C] C.descendants #=> [C]
- 一部のフレームワークでは独自実装しているらしい
- 2年前に提案されていたが議論が途中で止まっていて最近実装した PR が投げれれていた
[Feature #11927] Return value for Module#include
and Module#prepend
Module#include
とModule#prepend
の戻り値を変更しようという提案- 現状では戻り値としてレシーバが返ってくる
module A; end module B; end A.include B # => A A.ancestors # => [A, B] A.prepend B # => A A.ancestors # => [A, B]
- これを次のような戻り値にしないか、という提案
# prepend after include module A; end module B; end A.include B # => A/true A.prepend B # => nil/false/exception
# include after prepend module A; end module B; end A.prepend B # => A/true A.include B # => nil/false/exception
# include/prepend after include/include at superclass class A; end module B; end A.include M # => A/true class B < A; end B.include M # => nil/false/exception
- 便利そうではあるけど具体的なユースケースってあるのかなあ
[Feature #15573] Permit zero step in Numeric#step and Range#step
Numeric#step
のby:
引数には0
を渡すことができるが第二引数には0
を渡すとエラーになるNumeric#step
の挙動としては1.step(10, by: 1)
も1.step(10, 1)
も同じ意味になるNumeric#step
の仕様は こちらRange#step
はキーワード引数を受け取らないが同様の挙動
# これは無限ループ 1.step(10, by: 0) { p "hoge" } # これは実行時エラー # error: `step': step can't be 0 (ArgumentError) 1.step(10, 0) { p "hoge" } # ブロックを渡さない場合はエラーにならない p 1.step(10, 0).take(10) # => [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
1.step(10, 0)
でも動作するように緩和させようというチケット- ブロックを渡した場合と渡さなかった場合で挙動が異なる
1.step(10, 0) # => ok 1.step(10, 0){} # => ArgumentError: step can't be 0 (1..10).step(0) # => ok (1..10).step(0){} # => ArgumentError: step can't be 0
- また
1.step(10, 0) { break }
は動作しないが1.step(10, 0).each { break }
で同等の事ができる - 現在はこの変更に対するユースケースは何か?という議論がされている
- エッジケースではあるが以下のような仕様例が考えられる
# avg_object_size = 0 の場合でもエラーにならずに動いてほしい # その場合は lower_threshold が5個返ってくる (lower_threshold..upper_threshold).step(avg_object_size).take(5)
[Feature #15547] deprecate iterator? [Feature #17133] Add deprecate warning Kernel#iterator?
Kernel#iterator?
はほとんど使用されていない(非推奨になって る)ので削除しようという提案Kernel#iterator?
はKernel#block_given?
と同等のメソッド
RDoc
を見るとThe iterator? form is mildly deprecated.
と書いてある- すでにマージ済み
- https://bugs.ruby-lang.org/issues/15547#change-87303
- バージョンから使用すると(
-w
を付けると?)警告が出力されるようになる
merge, fix されたチケット
- [Feature #17122] Add category to Warning#warn
Warning#warn
に対してwarn(msg, category: nil)
みたいなcategory:
キーワード引数を追加する提案
- [Bug #17130] Method#super_method is broken for aliased methods
alias
されたメソッドに対してMethod#super_method
経由で呼ぶと意図しないメソッドが呼ばれていたバグの修正
- [Feature #15547] deprecate iterator?
#iterator?
を非推奨にするチケット
- [Bug #17017] Range#max & Range#minmax incorrectly use Float end as max
Range#max
Range#minmax
の戻り値を調整する提案- いろいろとあり最終的には現状の挙動を維持することになった