From: "jhawthorn (John Hawthorn) via ruby-core" Date: 2025-04-15T01:09:34+00:00 Subject: [ruby-core:121659] [Ruby Bug#21267] respond_to check in Class#allocate is inconsistent 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 '
': 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/