Project

General

Profile

Actions

Bug #17321

closed

Having a singleton class makes cloning imperfect

Added by ufuk (Ufuk Kayserilioglu) over 3 years ago. Updated about 3 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.0.0dev (2020-11-11T09:11:09Z master fa3670e6e4) [x86_64-darwin19]
[ruby-core:100801]

Description

Problem


Running the following reproduction script:

class Foo
  def self.foo; end
end

def report(klass, name)
  puts "  #{name}.instance_methods(false): #{klass.instance_methods(false)}"
end

def clone_and_compare(obj)
  cln = obj.clone

  report(obj.singleton_class, "obj.singleton_class")
  report(cln.singleton_class, "cln.singleton_class")
  report(obj.singleton_class.singleton_class, "obj.singleton_class.singleton_class")
  report(cln.singleton_class.singleton_class, "cln.singleton_class.singleton_class")
end

puts "## Case 1"
obj = Foo.new
clone_and_compare(obj)

puts "## Case 2"
obj = Foo.new
obj.singleton_class
clone_and_compare(obj)

puts "## Case 3"
obj = Foo.new
obj.singleton_class.singleton_class.send(:define_method, :method_on_s2) {}
clone_and_compare(obj)

gives the following output:

## Case 1
  obj.singleton_class.instance_methods(false): []
  cln.singleton_class.instance_methods(false): []
  obj.singleton_class.singleton_class.instance_methods(false): []
  cln.singleton_class.singleton_class.instance_methods(false): []
## Case 2
  obj.singleton_class.instance_methods(false): []
  cln.singleton_class.instance_methods(false): []
  obj.singleton_class.singleton_class.instance_methods(false): []
  cln.singleton_class.singleton_class.instance_methods(false): [:foo]
## Case 3
  obj.singleton_class.instance_methods(false): []
  cln.singleton_class.instance_methods(false): []
  obj.singleton_class.singleton_class.instance_methods(false): [:method_on_s2]
  cln.singleton_class.singleton_class.instance_methods(false): [:method_on_s2]

Case 2 is surprising, because the cloned object has different contents to the original.
It is surprising that clone.singleton_class.singleton_class has the method :foo whereas
obj.singleton_class.singleton_class does not have any methods.

Case 3 suggests, however, that clone.singleton_class.singleton_class should have the
same methods as the ones on obj.singleton_class.singleton_class.

This reproduction script gives the same output all the way from Ruby 2.0 up to Ruby-HEAD:
https://wandbox.org/permlink/hRM9OMgtd6nuscRz

Fix


@alanwu (Alan Wu) and me have put together a PR that makes Case 2 output identical to Case 1 output:
https://github.com/ruby/ruby/pull/3761

Updated by jeremyevans0 (Jeremy Evans) over 3 years ago

  • Status changed from Open to Closed

Updated by ufuk (Ufuk Kayserilioglu) over 3 years ago

@jeremyevans0 (Jeremy Evans) Thanks for closing the issue.

Can we get this fix backported to 2.5, 2.6 and 2.7 please? As noted in the original report, this bug is present all the way back to 2.0.

Thank you!

Updated by jeremyevans0 (Jeremy Evans) over 3 years ago

  • Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN to 2.5: REQUIRED, 2.6: REQUIRED, 2.7: REQUIRED

ufuk (Ufuk Kayserilioglu) wrote in #note-2:

@jeremyevans0 (Jeremy Evans) Thanks for closing the issue.

Can we get this fix backported to 2.5, 2.6 and 2.7 please? As noted in the original report, this bug is present all the way back to 2.0.

2.5 is unlikely, as that is in security maintenance mode and this is not a security fix. 2.6 and 2.7 are possibilities. However, it is up to the branch maintainers whether this will be backported. I've updated the backport information to show that a backport is requested.

Updated by nagachika (Tomoyuki Chikanaga) about 3 years ago

  • Backport changed from 2.5: REQUIRED, 2.6: REQUIRED, 2.7: REQUIRED to 2.5: REQUIRED, 2.6: REQUIRED, 2.7: DONE

ruby_2_7 82d72f14e7071218f3fd710f770d1ba31390f027 merged revision(s) ebb96fa8808317ad53a4977bff26cf755d68077e.

Updated by usa (Usaku NAKAMURA) about 3 years ago

  • Backport changed from 2.5: REQUIRED, 2.6: REQUIRED, 2.7: DONE to 2.5: REQUIRED, 2.6: DONE, 2.7: DONE

ruby_2_6 r67935 merged revision(s) ebb96fa8808317ad53a4977bff26cf755d68077e.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0