Ruby 3の機能を削除する


Ruby 3がリリースされたばかりです.しかし当然のことながら、私のコードのいくつかはRuby 3の破壊的な変更に問題がありました.
これらのほとんどすべてはRuby 3's changes to how keyword arguments are handled , でも私もan intriguing issue 私のsord型生成プロジェクトについて報告した.
を使用するRubySortedSet しかし、それはRuby 3から「依存性とパフォーマンス理由」のために取り除かれました.我々がそれを使おうとすると仮定してください.
irb(main)> SortedSet
RuntimeError (The `SortedSet` class has been extracted from the `set` library.You must use the `sorted_set` gem or other alternatives.)
うーん、そのエラーメッセージは何ですか?それは通常、存在しない定数を使用しようとするときに見るものではありません.次のようになります.
NameError (uninitialized constant SortedSet)
SortedSet もっと便利なエラーメッセージを与えます.
どのように、Rubyはこれをしますか?見てみましょう!
私の最初の推測では、Ruby 3がSortedSet クラスASortedSet 例外をスローするメソッドです.ルビーにとっては珍しいことではないKernel 持つmethods which look like classes , それで、私はこれがかなり良い推測であると思いました.しかし、nope、何もありませんSortedSet メソッド:
irb(main)> method(:SortedSet)
NameError (undefined method `SortedSet' for class `#<Class:#<Object:0x000056382e0a84c8>>')
少し深く掘るために、私はRuby interpreter source code . The lib/set.rb ファイルが答えを示した
autoload :SortedSet, "#{__dir__}/set/sorted_set"
SortedSetautoload . リファレンスSortedSet は、指定されたファイルを要求し、その定数を解決する必要があります.
確かに、我々が見ていた有用な例外は sorted_set ファイルautoload ポイント
begin
  require 'sorted_set'
rescue ::LoadError
  raise "The `SortedSet` class has been extracted from the `set` library." \
        "You must use the `sorted_set` gem or other alternatives."
end
これは、機能が壊れたり削除されたときに便利なエラーメッセージを提供する本当に巧妙な方法です.
しかし、それには1つのquirkがあります、そして、それは私が最初にこれを見させたバグの原因です.SortedSet まだ定数であるのでObject.constants 含まれます.しかし、この定数にアクセスすると、必ずしもsorted_set ジェム.これは、すべての利用可能な定数を反復処理することで例外をスローできることを意味します!
Object.constants.each do |c|
  p Object.const_get(c)
end

# => KeyError
# => Thread::Queue
# => IndexError
# ...etc, until boom!
# => RuntimeError (The `SortedSet` class has been extracted from the `set` library.You must use the `sorted_set` gem or other alternatives.)
私は、これが若干の重くメタプログラミングされた環境で問題であるのを見ることができます.
基本的には単なるエラーメッセージであるため、このアプローチはSortedSet 考える面白い.
「存在する定数を読む」という一般的な仮定を破っているのは、開発者を助けるかもしれないときに価値があります.
あるいは、Rubyのメタプログレッシブの有効性を最大にする一貫性キーですか?このようなエッジケースはRubyの内部を理解するのが難しい複雑さを導入しますか?
個人的には、このマイナータッチはRuby 3では大きなデザインの決定だと思います.あなたが他の考えを持っているならば、私は彼らを聞くことに興味があります!