[ruby-core:121659] [Ruby Bug#21267] respond_to check in Class#allocate is inconsistent
From:
"jhawthorn (John Hawthorn) via ruby-core" <ruby-core@...>
Date:
2025-04-15 01:09:34 UTC
List:
ruby-core #121659
Issue #21267 has been reported by jhawthorn (John Hawthorn).
----------------------------------------
Bug #21267: respond_to check in Class#allocate is inconsistent
https://bugs.ruby-lang.org/issues/21267
* Author: jhawthorn (John Hawthorn)
* Status: Open
* Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN
----------------------------------------
`Class#allocate` has an additional `rb_obj_respond_to(klass, rb_intern("allocate"))` check to forbid allocate being called on a class where it has been made private or undefined, even if used via ex. `bind_call`.
```
>> Rational.allocate
(irb):1:in '<main>': undefined method 'allocate' for class Rational (NoMethodError)
>> Class.instance_method(:allocate).bind_call(Rational)
(irb):1:in 'Class#allocate': calling Rational.allocate is prohibited (TypeError)
```
However I don't think this provides any additional protection from users accessing an uninitialized object, as the user can redefine allocate to anything to bypass the check:
```
>> Class.instance_method(:allocate).bind_call(Class.new(Rational) {def self.allocate; end})
=> (0/1)
```
Or even override `respond_to_missing?`
```
>> Class.instance_method(:allocate).bind_call(Class.new(Rational) {def self.respond_to_missing? *; true; end})
=> (0/1)
```
So I think we should remove this check. For classes that we need to forbid allocation we should use `rb_undef_alloc_func`.
The classes I see this used for are:
* MatchData
* Refinement
* Module
* Complex
* Rational
My main motivation is that this check makes `Class#allocate` slow. There are ways we could improve that, but I don't think the check as-is is useful. If there's an alternative, more robust, check we'd like to do instead of simply removing this I'd be happy to implement it.
This makes `allocate` ~75% faster.
```
|allocate_no_params | 19.009M| 20.087M|
| | -| 1.06x|
|allocate_allocate | 20.587M| 35.882M|
| | -| 1.74x|
```
https://github.com/ruby/ruby/pull/13116
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/