Fix conversion of singleton classes in Ruby #9342
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I found a nasty issue when passing an object who's singleton class was accessed as a Protobuf field value. In my case I was using a string and got this cryptic message:
After digging deeper I've discovered that Ruby has a weird way of representing a singleton class (also known as eigenclass in Ruby) — basically once it was accessed via the
Object#singleton_class
method the true class of an object becomes a wrapper (such as#<Class:#<String:0x00000001168372e8>>
in case of a string).This is normally an issue because all the class accessor methods in Ruby take this into account and unwrap the real class, so it's not even noticeable. However when using Ruby C API's
CLASS_OF()
method, it shows the wrapper class and therefore is not very usable with wrapped classes. Instead arb_obj_class
should be used, which will correctly account for wrapped classes. More details (as well as an example) can be found here — https://bugs.ruby-lang.org/issues/18428.The error itself is also pretty confusing because it's using
rb_class2name()
which is wrapper aware and shows the unwrapped class (which is not the same one that was used in the conditional).Note: I've included a test which should replicate this issue, however I wasn't able to run
rake test
locally. There seems to be a big circular dependency issue betweenruby/lib/google/protobuf/descriptor_dsl.rb
andruby/lib/google/protobuf/descriptor_pb.rb
(DSL depends on the generated proto, which itself is built using the DSL). Not sure how it was supposed to work. Hoping on the CI run to make sure everything is good.