Feature #20317
openRemoving the `allocate` method should cause `new` to fail
Description
When you remove the allocate
method from a class the you can't allocate the class via the allocate
method. However, you can allocate the class via the new
method:
class Foo; end
Foo.singleton_class.undef_method(:allocate)
begin
Foo.allocate # doesn't work, of course
rescue NoMethodError
end
begin
Class.instance_method(:allocate).bind_call(Foo) # also doesn't work
rescue TypeError
end
Foo.new # works?
I think that when we remove the allocate
method, the new
method should also fail as there is no allocate
method for new
to call.
Updated by jeremyevans0 (Jeremy Evans) 9 months ago
The current behavior may be what you want if you want to ensure that new instances of the class have #initialize
called on them. I suppose you could switch to making allocate
private, but that still would allow for send(:allocate)
.
If we disallow .new
if .allocate
is undefined, should we also disallow #dup
and #clone
, both of which also need to allocate an object?
Updated by tenderlovemaking (Aaron Patterson) 9 months ago
jeremyevans0 (Jeremy Evans) wrote in #note-1:
The current behavior may be what you want if you want to ensure that new instances of the class have
#initialize
called on them. I suppose you could switch to makingallocate
private, but that still would allow forsend(:allocate)
.If we disallow
.new
if.allocate
is undefined, should we also disallow#dup
and#clone
, both of which also need to allocate an object?
I think that makes sense. For example if you wanted to ensure a particular instance is a singleton:
class Foo; end
singleton = Foo.new
Foo.singleton_class.undef_method(:allocate)
# now there can only be one instance of `Foo` as new / allocate / dup / clone will raise
Updated by Dan0042 (Daniel DeLorme) 9 months ago
May I ask what is the use case for this?
The only reason I can think to undefine allocate
is if you want to allow only a single instance of the class, and in that case include Singleton
should do the job fine I think.