Класс # выделяет и использует его

18

После того, как вы прочитали Ссылка и более подробно рассмотрите метод выделения: Ссылка Мне стало очень любопытно.

Ruby был создан таким образом, что нам не нужно было вручную выделять или освобождать пространство для / с объектами, но нам дана возможность сделать это. Почему?

Каковы преимущества использования Ruby для выделения объектов вручную? В статье, которую я прочитал, был показан специальный метод инициализации, но его использование ограничено?

    
задан Robert 'Jet' Rowe 25.10.2012 в 01:44
источник
  • Системы сериализации (такие как маршал) должны иметь возможность создавать объект без вызова инициализации, поскольку инициализация может делать дорогостоящие или ненужные вещи, когда вы просто переписываете все. –  mu is too short 25.10.2012 в 03:58
  • Му, это действительно интересно. Можете ли вы привести дополнительные примеры или более подробное объяснение? –  sunnyrjuneja 25.10.2012 в 07:39

1 ответ

14

Основная причина, по которой 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 последовательно предоставляет такие точки расширения, независимо от того, будете ли вы использовать их регулярно. Роберт Клемм имеет отличную статью под названием Полный класс , которую я настоятельно рекомендую прочитать, если вы хотите увидеть насколько эта концепция дизайна была сделана в Ruby: -)

    
ответ дан Gregory Brown 07.11.2012 в 18:33
  • Спасибо, мне особенно нравится пример в реальном мире, который вы дали. –  Robert 'Jet' Rowe 07.11.2012 в 22:40
  • Я думаю, что пример должен сказать cattr_accessor: instance в конце. ... Кроме того, я задаюсь вопросом, можно ли достичь того же, позвонив супер, а не выделять. –  Jason Orendorff 24.06.2014 в 15:45
  • Пробовал. супер работает! Но тогда вам понадобится метод initialize, чтобы принять аргумент настроек. (Кстати, хотя такой код иногда неизбежен, чтобы сохранить обратную совместимость, пользователь может удивить, что настройки полностью игнорируются во второй раз!) –  Jason Orendorff 24.06.2014 в 15:55
  • Синглтон может использоваться для вашего случая использования, нет? –  Halil Özgür 20.08.2016 в 13:24
  • Нарушена ссылка на «Полный класс». У вас есть обновленный? Я не смог найти статью через Google. –  Hubro 08.09.2017 в 17:34