2021/02/18 今週の気になった bugs.ruby のチケット

内容は適当です。
今週と言っても今週みかけたチケットなだけでチケット自体は昔からあるやつもあります。
あくまでも『わたしが気になったチケット』で全ての bugs.ruby のチケットを載せているわけではありません。

[Misc #17591] Test frameworks and REPLs do not show deprecation warnings by default

  • テストフレームワークRSpec や test-unite)や REPL(irb とか)で非推奨の警告をデフォルトで出すようにしよう、というチケット
  • 既に test-unit 3.4.0 ではデフォルトで有効になっており RSpec でも同様のチケットが立てられている
  • また irb に関しては『初心者が使うと混乱する』という理由で同意はされていないようです
  • 個人的には Ruby 自体が『デフォルトでは非推奨の警告を出さないように決めた』ので基本的には(少なくとも組み込みの範囲では)デフォルトでは出さないようにしてほしい気持ちが強い
    • このケースは警告がでて、このケースは警告がでないみたいにすると一貫性もないし、ユーザは混乱するだけ
    • Ruby 2.7.2 の世界では個々で必要に応じて警告を出すようにすべき

[Bug #17590] M.prepend M has hidden side effect

  • M.prepend M を呼び出すとエラーになるが副作用があるというバグ報告
  • 以下のように M.prepend M を呼んだ場合とそうでない場合で差異がある
module M; end
class C; end
C.prepend M
C.include M

module M2; end
M2.prepend M
C.include M2

# M.prepend M を呼んでない場合
p C.ancestors # => [M, C, M2, Object, Kernel, BasicObject]


M.prepend M rescue nil
module M3; end
M3.prepend M
C.include M3

# M.prepend M を呼んだ場合
# M が複数追加されている…
p C.ancestors # => [M, C, M3, M, M3, M2, Object, Kernel, BasicObject]
  • これには2つの問題があるようで、1つは以下のように M.prepend M すると M.ancestors # => [M, M] となる問題
module M
end

# 継承リストは自身だけ
pp M.ancestors
# => [M]

begin
  # 自身を prepend するとエラーになる
  # これは Ruby 2.7 でも 3.0 でも同じ
  M.prepend M
rescue => e
  puts "error : #{e.message}"
  # => error : cyclic prepend detected
end

# M.prepend M はエラーになるが Ruby 3.0 では副作用がある
# 3.1-dev では修正済み
pp M.ancestors
# 2.7 => [M]
# 3.0 => [M, M]
# 3.1 => [M]