[#122258] [Ruby Misc#21367] Remove link to ruby-doc.org from www.ruby-lang.org/en/documentation/ — "p8 (Petrik de Heus) via ruby-core" <ruby-core@...>
Issue #21367 has been reported by p8 (Petrik de Heus).
11 messages
2025/05/23
[ruby-core:121899] [Ruby Bug#21267] respond_to check in Class#allocate is inconsistent
From:
"jhawthorn (John Hawthorn) via ruby-core" <ruby-core@...>
Date:
2025-05-08 04:55:51 UTC
List:
ruby-core #121899
Issue #21267 has been updated by jhawthorn (John Hawthorn).
> Or core types could actually define dup & clone as overridden methods, and not use the alloc function at all and so use rb_undef_alloc_func().
That seems the cleanest actually, WDYT?
Yes. The only options that work are to `rb_undef_alloc_func` or returning something safe from the alloc func. The `alloc_prohibited` approach we tried is a dead end.
As far as I can tell in current Ruby uninitialized MatchData, Refinement, Module, Complex, Rational do not crash the VM (if they do we need to fix that, because again, users can access that today). Which is why we should remove it. If we want to adjust those classes to `rb_undef_alloc_func` that seems like a good idea and we can do that later.
----------------------------------------
Bug #21267: respond_to check in Class#allocate is inconsistent
https://bugs.ruby-lang.org/issues/21267#change-112968
* 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/