Подтвердить что ты не робот

Классы Ruby: инициализировать self vs. @variable

Может кто-нибудь объяснить разницу между инициализацией "self" и наличием @variables при определении классов?

Здесь пример

class Child < Parent
  def initialize(self, stuff):
    self.stuff = stuff
    super()
  end
end

Итак, в этом случае, не могу ли я заменить self.stuff на @stuff? Какая разница? Кроме того, super() означает только то, что находится в методе инициализации родителя, который должен просто наследовать его правильно?

4b9b3361

Ответ 1

В общем случае нет, self.stuff = stuff и @stuff = stuff разные. Первый метод вызывает метод stuff= для объекта, а последний непосредственно задает переменную экземпляра. Первый вызывает метод, который может быть общедоступным (если специально не объявлено частным в классе), тогда как последний всегда задает переменную частного экземпляра.

Обычно они выглядят одинаково, потому что обычно для классов attr_accessor :stuff. attr_accessor примерно эквивалентно следующему:

def stuff
  @stuff
end

def stuff=(s)
  @stuff = s
end

Таким образом, в этом случае они функционально идентичны. Тем не менее, можно определить публичный интерфейс, чтобы обеспечить разные результаты и побочные эффекты, что сделало бы эти два "назначения" различными:

def stuff
  @stuff_called += 1    # Keeps track of how often this is called, a side effect
  return @stuff
end

def stuff=(s)
  if s.nil?             # Validation, or other side effect. This is not triggered when setting the instance variable directly
    raise "Argument should not be nil"
  end
  @stuff = s
end

Ответ 2

Фактически вы не можете использовать self.stuff=, если вы специально не создаете attr_writer для изменения этого значения.

Фактически они эквивалентны:

class Child
  attr_writer :stuff
end

class Child
  def stuff=(val)
    @stuff = val
  end
end

Чаще всего используется attr_writer, если это необходимая функциональность, а не явный метод. Но вы часто будете использовать явный метод, если вы хотите выполнить дополнительную проверку ошибок или изменить способ работы задания.

На вопрос о том, когда использовать @stuff = и когда использовать self.stuff =, я бы использовал первое, если у вас есть только простые назначения, и если ваш класс прост и будет двигаться к последнему, если ваши требования могут стать более сложным. Есть много других причин, но это скорее вопрос стиля, чем что-либо еще.