Вашего контекст не то же самое (см):
module ApplicationHelper
p self # => ApplicationHelper
def method1
p self # => #<OtherClass:0x007fbe032cf6f0> an instance of an object
end
end
Рубин не работает, как Java в том смысле, что вы не в состоянии установить переменный экземпляр объекта в контексте модуля (или класс), как и вы. В вашем коде @var1 = MyModel::CONST1.each_with_index.map { |item, i| [item, i] }
определяет переменную экземпляра var1
на фактическом объекте модуля ApplicationHelper
, не на любом экземпляре.
В Ruby, когда вы только хотите определить переменные один раз, мы используем ||=
запоминания трюк:
module ApplicationHelper
def method1
@var1 ||= MyModel::CONST1.each_with_index.map { |item, i| [item, i] }
end
end
Это трюк, который использует тот факт, что первый раз, когда вы ссылаетесь на переменной она будет nil
и nil
считается неуловимым в Ruby. Таким образом, выше строка ярлык для записи:
@var1 || @var1 = MyModel::CONST1.each_with_index.map { |item, i| [item, i] }
ПРИМЕЧАНИЕ: Имейте в виду, что если @var1
может быть значения nil
или false
это будет повторно оценивать его каждый раз. Однако в этом случае. Поскольку вы используете Enumerable#map, вы получите []
, а не nil
, если товаров нет. Таким образом, использование будет таким, как ожидалось в этой ситуации.
У этого есть проблема с кромкой при первом вызове method1
, потому что вы используете его для установки значения по умолчанию. Если мы вместо этого используем передачу сообщений вместо прямого доступа к переменной, мы можем достичь того, что вы ищете:
module ApplicationHelper
def method1(v1, v2, v3 = var1.first)
#....
# all further access to @var1 is done by passing the message var1
tmp = var1.select{ ... }
end
def var1
@var1 ||= MyModel::CONST1.each_with_index.map { |item, i| [item, i] }
end
end