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) 10 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) 10 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) 10 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.