From a63e979853783601a60228b45741f8b3776e5507 Mon Sep 17 00:00:00 2001 From: "NARUSE, Yui" Date: Thu, 21 Mar 2024 10:45:01 +0900 Subject: merge revision(s) d19d683a354530a27b4cbb049223f8dc70c75849,de1a586ecc2ee7f465f0c0a69291054136a3a819: [Backport #20250] (#10308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rb_obj_setup: do not copy RUBY_FL_SEEN_OBJ_ID [Bug #20250] We're seting up a new instance, so it never had an associated object_id. proc.c: get rid of `CLONESETUP` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Bug #20253] All the way down to Ruby 1.9, `Proc`, `Method`, `UnboundMethod` and `Binding` always had their own specific clone and dup routine. This caused various discrepancies with how other objects behave on `dup` and `clone. [Bug #20250], [Bug #20253]. This commit get rid of `CLONESETUP` and use the the same codepath as all other types, so ensure consistency. NB: It's still not accepting the `freeze` keyword argument on `clone`. Co-Authored-By: Étienne Barrié --- spec/ruby/core/method/clone_spec.rb | 15 +++++++-------- spec/ruby/core/method/dup_spec.rb | 15 +++++++++++++++ spec/ruby/core/method/shared/dup.rb | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 spec/ruby/core/method/dup_spec.rb create mode 100644 spec/ruby/core/method/shared/dup.rb (limited to 'spec/ruby/core/method') diff --git a/spec/ruby/core/method/clone_spec.rb b/spec/ruby/core/method/clone_spec.rb index 3fe4000fb7..b0eb5751a9 100644 --- a/spec/ruby/core/method/clone_spec.rb +++ b/spec/ruby/core/method/clone_spec.rb @@ -1,14 +1,13 @@ require_relative '../../spec_helper' -require_relative 'fixtures/classes' +require_relative 'shared/dup' describe "Method#clone" do - it "returns a copy of the method" do - m1 = MethodSpecs::Methods.new.method(:foo) - m2 = m1.clone + it_behaves_like :method_dup, :clone - m1.should == m2 - m1.should_not equal(m2) - - m1.call.should == m2.call + it "preserves frozen status" do + method = Object.new.method(:method) + method.freeze + method.frozen?.should == true + method.clone.frozen?.should == true end end diff --git a/spec/ruby/core/method/dup_spec.rb b/spec/ruby/core/method/dup_spec.rb new file mode 100644 index 0000000000..e3e29d8a68 --- /dev/null +++ b/spec/ruby/core/method/dup_spec.rb @@ -0,0 +1,15 @@ +require_relative '../../spec_helper' +require_relative 'shared/dup' + +describe "Method#dup" do + ruby_version_is "3.4" do + it_behaves_like :method_dup, :dup + + it "resets frozen status" do + method = Object.new.method(:method) + method.freeze + method.frozen?.should == true + method.dup.frozen?.should == false + end + end +end diff --git a/spec/ruby/core/method/shared/dup.rb b/spec/ruby/core/method/shared/dup.rb new file mode 100644 index 0000000000..1a10b90689 --- /dev/null +++ b/spec/ruby/core/method/shared/dup.rb @@ -0,0 +1,32 @@ +describe :method_dup, shared: true do + it "returns a copy of self" do + a = Object.new.method(:method) + b = a.send(@method) + + a.should == b + a.should_not equal(b) + end + + ruby_version_is "3.4" do + it "copies instance variables" do + method = Object.new.method(:method) + method.instance_variable_set(:@ivar, 1) + cl = method.send(@method) + cl.instance_variables.should == [:@ivar] + end + + it "copies the finalizer" do + code = <<-RUBY + obj = Object.new.method(:method) + + ObjectSpace.define_finalizer(obj, Proc.new { STDOUT.write "finalized\n" }) + + obj.clone + + exit 0 + RUBY + + ruby_exe(code).lines.sort.should == ["finalized\n", "finalized\n"] + end + end +end -- cgit v1.2.3