From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on starla X-Spam-Level: X-Spam-Status: No, score=-1.2 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,MAILING_LIST_MULTI,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=4.0.1 Authentication-Results: dcvr.yhbt.net; dkim=pass (1024-bit key; unprotected) header.d=ml.ruby-lang.org header.i=@ml.ruby-lang.org header.a=rsa-sha256 header.s=mail header.b=1jz7LJ/K; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ruby-lang.org header.i=@ruby-lang.org header.a=rsa-sha256 header.s=s1 header.b=AR/CzLeU; dkim-atps=neutral Received: from nue.mailmanlists.eu (nue.mailmanlists.eu [94.130.110.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id C35B61F4EF for ; Sat, 30 Aug 2025 00:17:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ml.ruby-lang.org; s=mail; t=1756513061; bh=hVl21Q3ivwUL6bfc4KfOnWiSeEKjM8Fkai01sYcGhWI=; h=Date:References:To:Reply-To:Subject:List-Id:List-Archive: List-Help:List-Owner:List-Post:List-Subscribe:List-Unsubscribe: From:Cc:From; b=1jz7LJ/K8oKIITVwp7mIk+72BuFF3U+iHTAJt6apA8Hc6Nc/uKN1WGSxqgUo2CEHv zubYdtw6TfLNR18IGMtmEsgsZsjXUbY0ULsaSWkzLT/SA885okwH1aRgZ4FbJCrg+C EKAN3QSGs94kI09l3VwNm5F4IOlf12aNm9Pihb04= Received: from nue.mailmanlists.eu (localhost [IPv6:::1]) by nue.mailmanlists.eu (Postfix) with ESMTP id 6025C48E1A for ; Sat, 30 Aug 2025 00:17:41 +0000 (UTC) Authentication-Results: nue.mailmanlists.eu; dkim=pass (2048-bit key; unprotected) header.d=ruby-lang.org header.i=@ruby-lang.org header.a=rsa-sha256 header.s=s1 header.b=AR/CzLeU; dkim-atps=neutral Received: from s.wrqvwxzv.outbound-mail.sendgrid.net (s.wrqvwxzv.outbound-mail.sendgrid.net [149.72.154.232]) by nue.mailmanlists.eu (Postfix) with ESMTPS id D9EA948D82 for ; Sat, 30 Aug 2025 00:16:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ruby-lang.org; h=date:from:references:subject:mime-version:content-type: content-transfer-encoding:list-id:to:cc:content-type:date:from:subject:to; s=s1; bh=Cl039mZWRCmMt5rIr7Xsrl+V1g75fQZE3xkQ7ObNT48=; b=AR/CzLeUOTDls2LE3b8SIJ0/MsLeVrITCAqbXOvvyTz/vEt3/UkEwPnsep8RB3npHDZV asK/y3tjLqZmoq/SGxWe9P0kCdhYOkSZKIYyCLldP0fI5YprhgujrYKtOmCaWv66xrRpN5 mmnQG1CgWUC3Qnoytth+0qTZ1xRbK2dCHLbsgOwmrv6co9ed+91szPg39UDVAF91JznQW7 luVsBOJjK1H/XWK3gW2HJ6lXiLHeOebosJUpSIBM2Yl8Skhsta7HyOYqRWcWdJM8//hoE1 A35trPxmSYeQVoNMOeahXbzXvpoxvVWtZBz0M/IiU6hgxMgk9lLySk1Q5pGM8gcw== Received: by recvd-7748d67658-m7v6r with SMTP id recvd-7748d67658-m7v6r-1-68B242E4-6 2025-08-30 00:16:36.451415346 +0000 UTC m=+7457563.284184943 Received: from herokuapp.com (unknown) by geopod-ismtpd-36 (SG) with ESMTP id 1tKYkwp2R5eFS2ZSuBWlRg for ; Sat, 30 Aug 2025 00:16:36.399 +0000 (UTC) Date: Sat, 30 Aug 2025 00:16:36 +0000 (UTC) Message-ID: References: Mime-Version: 1.0 X-Redmine-Project: ruby-master X-Redmine-Issue-Tracker: Bug X-Redmine-Issue-Id: 21538 X-Redmine-Issue-Author: chucke X-Redmine-Issue-Priority: Normal X-Redmine-Sender: jeremyevans0 X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-Redmine-MailingListIntegration-Message-Ids: 99938 X-SG-EID: =?us-ascii?Q?u001=2ELyyp8a6L4BPdoBZ5kcNQuEdalXgUnCKLcPykf2c9d2sTWfvALBzqM4Ij+?= =?us-ascii?Q?Jg9Prp2eVDkf9lIZhzc05KfUT4Npfgnigb95d+v?= =?us-ascii?Q?hGuAMoCQYcKFKOsnHWSojeYu6LjaYLSVrq2qQhO?= =?us-ascii?Q?38BBGSRaxMF6k0PZoVgD6PSkJBl2aSLlQjlqqh9?= =?us-ascii?Q?qgZZGfXZtB50XlQpuoagtVZgOJDIDOEim3gn8f2?= =?us-ascii?Q?vJJbJEakvug=2FbAXZoXwZ2dYS4X0Ap7V=2FpBOgwSb?= =?us-ascii?Q?iZkxJpZJhhK1paA5BzZf+N4ZMw=3D=3D?= To: ruby-core@ml.ruby-lang.org X-Entity-ID: u001.I8uzylDtAfgbeCOeLBYDww== Message-ID-Hash: OTC7EN3HL265LCZGXTD2AUAU2ATHSYSQ X-Message-ID-Hash: OTC7EN3HL265LCZGXTD2AUAU2ATHSYSQ X-MailFrom: bounces+313651-b711-ruby-core=ml.ruby-lang.org@em5188.ruby-lang.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: Ruby developers Subject: [ruby-core:123131] [Ruby Bug#21538] initialize_dup not called when duping class/module List-Id: Ruby developers Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: "jeremyevans0 (Jeremy Evans) via ruby-core" Cc: "jeremyevans0 (Jeremy Evans)" Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Issue #21538 has been updated by jeremyevans0 (Jeremy Evans). The example given isn't a bug. `initialize_dup` is called on the new instance (in this example, the instance of `Class`), and `dup` does not copy singleton classes. If you define `Class#inititialize_dup`, it works as expected: ```ruby class A def initialize_dup(_) puts "dup instance" super end end class Class def initialize_dup(_) puts "dup class" super end end A.new.dup # prints "dup instance" A.dup # prints "dup class" ``` `dup` is different than `clone`, because `clone` copies the singleton class, and therefore will pick up singleton methods: ```ruby class A def initialize_clone(_) puts "clone instance" super end def self.initialize_clone(_) puts "clone class" super end end A.new.clone # prints "clone instance" A.clone # prints "clone class" ``` That being said, there are two definite bugs and another probable bug in `Class#dup`, as evidenced by this example: ```ruby class Class def initialize_dup(_) p ancestors p singleton_class.ancestors super end end class B def self.initialize_dup(_) puts "dup class" super end end class A < B end puts p A.ancestors p A.singleton_class.ancestors puts C = A.dup puts p C.ancestors p C.singleton_class.ancestors ``` Output on Ruby 3.4 (with comments on bugs): ``` [A, B, Object, Kernel, BasicObject] [#, #, #, #, Class, Module, Object, Kernel, BasicObject] # Probable Bug: During initialize_dup, ancestors are missing, # and therefore ancestor initialize_dup singleton method not called [#] [#>, Class, Module, Object, Kernel, BasicObject] # Definite Bug 1: after dup, singleton class ancestors are missing [C, B, Object, Kernel, BasicObject] [#, Class, Module, Object, Kernel, BasicObject] ``` Output on master branch: ``` [A, B, Object, Kernel, BasicObject] [#, #, #, #, Class, Module, Object, Kernel, BasicObject] # Definite Bug 2: calling singleton_class inside Class#initialize_dup # results in TypeError [#] [#>, Class, Module, Object, Kernel, BasicObject] -:5:in 'Module#initialize_copy': already initialized class (TypeError) from -:5:in 'Kernel#initialize_dup' from -:5:in 'Class#initialize_dup' from -:25:in 'Kernel#dup' from -:25:in '
' ``` The reason I call the first bug probable and not definite is that it is at least defensible that ancestor setup occurs inside `dup`, but after the call to `Class#initialize_dup`. I still think it should be considered a bug and fixed. I'm guessing fixing definite bug 2 requires fixing the probable bug. For `clone`, there is a similar issue of missing ancestors (but not singleton class ancestors) inside `initialize_clone`: ```ruby class B def self.initialize_clone(_) p ancestors p singleton_class.ancestors puts "clone class" super end end class A < B end puts p A.ancestors p A.singleton_class.ancestors puts C = A.clone puts p C.ancestors p C.singleton_class.ancestors ``` Output: ``` [A, B, Object, Kernel, BasicObject] [#, #, #, #, Class, Module, Object, Kernel, BasicObject] # Probable bug: During initialize_clone, ancestors are missing [#] [#>, #, #, #, Class, Module, Object, Kernel, BasicObject] clone class [C, B, Object, Kernel, BasicObject] [#, #, #, #, Class, Module, Object, Kernel, BasicObject] ``` ---------------------------------------- Bug #21538: initialize_dup not called when duping class/module https://bugs.ruby-lang.org/issues/21538#change-114458 * Author: chucke (Tiago Cardoso) * Status: Open * ruby -v: 3.4.5 * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN ---------------------------------------- Not sure whether this is expected behaviour or not, but just leaving it here to start the debate on whether callbacks like `initialize_dup` are supposed to be called when a module or class is duped (the same happens with `initialize_copy` and `initialize_clone` btw): class A def initialize_dup(_) puts "dup instance" super end def self.initialize_dup(_) puts "dup class" super end end A.new.dup #=> "dup instance" A.dup #=> nothing -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/