Ответ 1
Переменные экземпляра причины, используемые для классов в Ruby, - это то, что классы Ruby являются экземплярами сами (экземпляры класса Class). Попробуйте сами, проверив DummyClass.class
. В языке С# в Ruby нет "статических методов", потому что каждый метод определен (или унаследован) каким-то экземпляром и вызывается в каком-то экземпляре. Соответственно, они могут получить доступ к любым переменным экземпляра, которые будут доступны для вызываемого абонента.
Так как 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
и вызвать его. Было бы нецелесообразно назначать переменные экземпляра здесь, потому что вы не сказали бы, что вызывающий контекст здесь (средство визуализации) содержит эту информацию в экземпляре. В самом рендерере нет "ссылки для ссылки", и, следовательно, он не должен быть похоронен в переменной экземпляра.