您的上下文不一样(请参阅):
module ApplicationHelper
p self # => ApplicationHelper
def method1
p self # => #<OtherClass:0x007fbe032cf6f0> an instance of an object
end
end
Ruby 不像 Java 那样工作,因为您不能像以前那样在模块(或类)的上下文中设置对象实例变量。在您的代码中,是在实际模块 object 上@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
这个技巧利用了这样一个事实,即您第一次引用一个变量时,它会在 Ruby 中被认为很容易nil
。nil
所以上面这行是写法的捷径:
@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