Project

General

Profile

Actions

Feature #22376

open

Undefine the allocator for Class

Feature #22376: Undefine the allocator for Class
1

Added by jhawthorn (John Hawthorn) about 11 hours ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:126832]

Description

Uninitialized classes, created by Class.allocate, are a recurring source of bugs (most recently #22341). Every place that inspects a class's superclass chain has to check whether the class has been initialized, and it's easy to forget one.

I'd like to propose that we forbid Class.allocate, as we already do for several other core types (Proc, Method, UnboundMethod, Binding).

To do this we:

  • Undefine the allocator for Class (rb_undef_alloc_func)
  • Replace Class#initialize with a Class.new singleton method that allocates and initializes in one step.
  • Define Class#dup and Class#clone so that copying a class still works

Class can't be subclassed, so I don't think we need to worry about calling initialize. The only place I found Class.allocate via gem-codesearch were copies of ruby/spec, so I don't think forbidding that will cause problems.

Before:

klass = Class.allocate
Class.new(klass) # 'Class#initialize': can't inherit uninitialized class (TypeError)
klass.superclass # 'Class#superclass': uninitialized class (TypeError)

After:

Class.allocate # undefined method 'allocate' for class Class (NoMethodError)
Class.instance_method(:allocate).bind_call(Class) # 'Class#allocate': allocator undefined for Class (TypeError)

PR: https://github.com/ruby/ruby/pull/18964


Related issues 2 (2 open0 closed)

Related to Ruby - Feature #21852: New improved allocator function interfaceOpenActions
Related to Ruby - Feature #21963: A solution to completely avoid allocated-but-uninitialized objectsOpenActions
Actions

Also available in: PDF Atom