[ruby-core:124820] [Ruby Feature#6478] BasicObject#__class__
Issue #6478 has been updated by trinistr (Alexander Bulancov). jneen (Jeanine Adkisson) wrote in #note-16:
I wonder if exposing a static `Object.class_of(thing)` would be appropriate? There's also the singleton_class to consider as well.
This is an interesting idea. It would solve the problems around this, in a simpler way than an `UnboundMethod`. But it defintely feels off for Ruby, though we have some methods like that (`Regexp.linear_time?` comes to mind). Eregon (Benoit Daloze) wrote in #note-19:
I think at least it's clear it's not good to go towards having every `Kernel` method as a `__x__` variant on BasicObject. Also even `__send__` and `__id__` can be redefined, so the `KERNEL_CLASS = Kernel.instance_method(:class); KERNEL_CLASS.bind_call(obj)` approach is in fact safer.
So my take on this is `KERNEL_CLASS = Kernel.instance_method(:class); KERNEL_CLASS.bind_call(obj)` is good enough, and also most BasicObject subclasses should implement Kernel-like methods.
Concrete examples from real code where this is not good enough would most likely be helpful to move this forward if people want that.
I agree, porting all methods from Kernel is unreasonable. It's just that having access to object's class is fundamental and would provide replacements for many generic methods (especially `methods` and co). In my experience, `__class__` would be much more useful than `__id__`, for example. IMHO, redefining basic methods is not a compelling argument, `Kernel#class` could be redefined too. On the other hand, `#class` being redefined [happens](https://github.com/search?q=%2Fdef+class%5Cb%2F+language%3Aruby&ref=searchresults&type=code&utf8=%E2%9C%93) more often than for `#__class__`.
`KERNEL_CLASS = Kernel.instance_method(:class)`
This looks even less Ruby-like to me than a silly method name :p Also, due to constant resolution, placing such constants requires extra consideration or littering the code with them.
Concrete examples from real code where this is not good enough would most likely be helpful to move this forward if people want that.
```ruby Ractor.shareable?(Kernel.instance_method(:class)) # => false ``` So Ractor-compatible code can not use such a constant (relevant #17513 is still open). And just basic stuff like this would be much easier to write: ```ruby def my_chunkers(collection) raise ArgumentError, "#{collection.__class__} is not enumerable" unless Enumerable === collection collection.chunk(&:itself) end ``` byroot (Jean Boussier) wrote in #note-18:
Why not add BasicObject#class?
I suspect that would break various proxy classes in gems. Might not be a huge deal.
That's that I thought, too, there probably is code relying on `class` being proxied, otherwise I would push for that name. ---------------------------------------- Feature #6478: BasicObject#__class__ https://bugs.ruby-lang.org/issues/6478#change-116441 * Author: trans (Thomas Sawyer) * Status: Feedback * Assignee: matz (Yukihiro Matsumoto) ---------------------------------------- How else is one supposed to get the class of a subclass of BasicObject? -- https://bugs.ruby-lang.org/
participants (1)
-
trinistr (Alexander Bulancov)