From: "ufuk (Ufuk Kayserilioglu)" Date: 2021-12-23T16:52:50+00:00 Subject: [ruby-core:106785] [Ruby master Bug#18428] Calling Object#singleton_class mutates object's class from the C API's perspective Issue #18428 has been updated by ufuk (Ufuk Kayserilioglu). This is by design, that's how singleton classes work. The singleton class subclasses from the original class and becomes the class of the object itself. The Ruby `class` method skips the singleton class and exposes the original class instead. ---------------------------------------- Bug #18428: Calling Object#singleton_class mutates object's class from the C API's perspective https://bugs.ruby-lang.org/issues/18428#change-95488 * Author: antstorm (Anthony Dmitriyev) * Status: Open * Priority: Normal * ruby -v: ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [arm64-darwin20] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN ---------------------------------------- Hi, I'm not 100% sure if this is an actual bug, but it feels like it. When a `Object#singleton_class` method is called on an object it swaps the object's class with a singleton's class (as far as `CLASS_OF` C call is concerned). Here's a simple example to reproduce the issue: 1. The C extension that adds a `#c_class` method to the Object, returning back the value of `CLASS_OF` call ``` c #include "ruby.h" #include "extconf.h" static VALUE c_class(VALUE self) { return CLASS_OF(self); } void Init_c_class(void) { rb_define_method(rb_cObject, "c_class", c_class, 0); } ``` 2. With that extension required, we can expose the issue from the console: ```ruby >> a = 'test' => "test" >> a.class => String >> a.c_class => String >> a.singleton_class => #> >> a.class => String >> a.c_class => #> ``` I would expect the last call to `c_class` to return the same value as previously ��� `String`, instead it returns a singleton class. Originally noticed this behaviour when passing a string to Google protobuf generated files, which raises this error ��� https://github.com/protocolbuffers/protobuf/blob/master/ruby/ext/google/protobuf_c/convert.c#L161. If the string had `singleton_class` called on it this would raise. -- https://bugs.ruby-lang.org/ Unsubscribe: