Причина, по которой переменные экземпляра работают с классами в Ruby, заключается в том, что классы Ruby сами являются экземплярами (экземплярами класса Class ).Попробуйте сами, проверив DummyClass.class
.В Ruby не существует «статических методов» в смысле C #, потому что каждый метод определен (или унаследован) в некотором экземпляре и вызван в некотором экземпляре.Соответственно, они могут получить доступ к любым переменным экземпляра, которые могут быть доступны в вызываемом объекте.
Поскольку DummyClass
является экземпляром, он может просто иметь свои собственные переменные экземпляра.Вы даже можете получить доступ к этим переменным экземпляра, если у вас есть ссылка на класс (что должно быть всегда, потому что имена классов являются константами).В любой момент вы сможете вызвать ::DummyClass.instance_variable_get(:@arr)
и получить текущее значение этой переменной экземпляра.
Что касается того, стоит ли это делать, это зависит от методов .
Если @arr
логически является «состоянием» экземпляра / класса DummyClass
, сохраните его в переменной экземпляра.Если @arr
используется только в dummy_method2
в качестве рабочего ярлыка, передайте его в качестве аргумента.Чтобы привести пример, где используется подход с использованием переменной экземпляра, рассмотрим ActiveRecord в Rails.Это позволяет вам сделать это:
u = User.new
u.name = "foobar"
u.save
Здесь имя, которое было назначено пользователю, является данными, которые законно принадлежат пользователю.Если перед вызовом #save
кто-то спросит «как зовут пользователя в данный момент», вы ответите «foobar».Если вы углубитесь во внутренние ресурсы (вы будете копаться очень глубоко и в метапрограммировании, вы обнаружите, что они используют переменные экземпляра именно для этого).
Пример, который я использовал, содержит дваотдельные публичные призывы.Чтобы увидеть случай, когда переменные экземпляра все еще используются, несмотря на то, что выполняется только один вызов, посмотрите на реализацию ActiveRecord #update_attributes
.Тело метода просто load(attributes, false) && save
.Почему #save
не передаются никакие аргументы (например, новый name
), даже если он находится в теле сохранения где-то вроде UPDATE users SET name='foobar' WHERE id=1;
?Это потому, что такие вещи, как имя, являются информацией, которая принадлежит экземпляру.
И наоборот, мы можем рассмотреть случай, когда переменные экземпляра не имеют смысла использовать.Посмотрите на реализацию #link_to_if
, метод, который принимает аргумент boolean-ish (обычно это выражение в исходном коде) наряду с аргументами, которые обычно принимаются #link_to
, такими как URL для ссылки на,Когда логическое условие истинно, ему необходимо передать остальные аргументы в #link_to
и вызвать его.Не имеет смысла назначать здесь переменные экземпляра, потому что вы не сказали бы, что вызывающий контекст здесь (средство визуализации) содержит эту информацию в экземпляре.Само средство визуализации не имеет «URL-адреса для ссылки», и, следовательно, его не следует скрывать в переменной экземпляра.