Ответ 1
Основная причина allocate
заключается в том, чтобы позволить вам создавать пользовательские конструкторы для ваших объектов. Как упоминалось в статье, вы можете представить себе метод SomeClass.new
, выполнив по умолчанию следующее:
class SomeClass
def self.new(*a, &b)
obj = allocate
# initialize is a private instance method by default!
obj.send(:initialize, *a, &b)
end
end
Несмотря на то, что говорит документация, существование метода allocate
заключается не столько в управлении памятью, сколько в предоставлении некоторого более тонкого контроля над жизненным циклом создания объекта. Большую часть времени вам не понадобится эта функция, но она полезна для определенных случаев с краями.
Например, в почтовой системе Newman я использовал эту технику для реализовать поддельный конструктор для объекта TestMailer; он реализовал метод new
для совместимости API, но фактически вернул один экземпляр, независимо от того, сколько раз он был вызван:
class Newman::TestMailer
def self.new(settings)
return self.instance if instance
# do some Mail gem configuration stuff here
self.instance = allocate
end
attr_accessor :instance
end
Я не видел много других вариантов использования, кроме переопределения new
, как показано выше (хотя я предполагаю, что некоторые странные средства сериализации также используют эту функцию). Но имея в виду это, стоит отметить, что Ruby последовательно предоставляет такие точки расширения, независимо от того, будете ли вы использовать их регулярно. У Роберта Клемма есть замечательная статья под названием The Complete Class, которую я настоятельно рекомендую прочитать, если вы хотите увидеть, насколько эта концепция дизайна была сделана в Ruby: -)