😎

[Bug #21538] class/module を .dup しても .initialize_dup が呼び出されないバグ報告

に公開

[Bug #21538] initialize_dup not called when duping class/module

  • class / module のオブジェクトを .dup したときに .initialize_dup が呼び出されないというバグ報告
class A
  def initialize_dup(_)
    puts "dup instance"
    super
  end

  def self.initialize_dup(_)
    puts "dup class"
    super
  end
end

# インスタンスオブジェクトの場合は #initialize_dup が呼び出される
A.new.dup
# => "dup instance"

# 一方でクラスオブジェクトの場合は .initialize_dup が呼び出されない
A.dup
# => nothing
  • これなんですが Module#initialize_dup を直接再定義した場合だとそっちは呼び出されるぽいんですよね〜
class Module
  def initialize_dup(_)
    puts "Module#initialize_dup"
    super
  end
end

class A
  def self.initialize_dup(_)
    puts "dup class"
    super
  end
end

A.dup
# => "Module#initialize_dup"
  • なので定義するメソッドが違うのかも…?と思ったんですが A.initialize_dupModule#initialize_dup が上書きされているみたいなので定義しているメソッド自体は問題なさそう?
class Module
  def initialize_dup(_) = super
end

class A
end

# これは Module#initialize_dup の定義を参照している
pp A.method(:initialize_dup)
# => #<Method: #<Class:A>(Module)#initialize_dup(_) test.rb:2>

def A.initialize_dup(_) = super


# A.initialize_dup の定義後はそれを参照している
pp A.method(:initialize_dup)
# => #<Method: A.initialize_dup(_) test.rb:12>
  • 内部実装で直接 Module#initialize_dup を呼び出すようになっているんですかね?
  • この不具合は開発版の Ruby 3.5-dev で修正済み
class A
  def initialize_dup(_)
    puts "dup instance"
    super
  end

  def self.initialize_dup(_)
    puts "dup class"
    super
  end
end

A.dup
# Ruby 3.4 => nothing
# Ruby 3.5 => dup class
GitHubで編集を提案

Discussion