Классы Ruby: инициализировать self vs. @variable
Может кто-нибудь объяснить разницу между инициализацией "self" и наличием @variables при определении классов?
Здесь пример
class Child < Parent
def initialize(self, stuff):
self.stuff = stuff
super()
end
end
Итак, в этом случае, не могу ли я заменить self.stuff
на @stuff
? Какая разница? Кроме того, super()
означает только то, что находится в методе инициализации родителя, который должен просто наследовать его правильно?
Ответы
Ответ 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 =
, я бы использовал первое, если у вас есть только простые назначения, и если ваш класс прост и будет двигаться к последнему, если ваши требования могут стать более сложным. Есть много других причин, но это скорее вопрос стиля, чем что-либо еще.