显然,||=
不会工作
def x?
@x_query ||= expensive_way_to_calculate_x
end
因为如果结果是false
或nil
,那么expensive_way_to_calculate_x
就会一遍又一遍地运行。
目前,我所知道的最好的方法是将值放入Array
def x?
return @x_query.first if @x_query.is_a?(Array)
@x_query = [expensive_way_to_calculate_x]
@x_query.first
end
有没有更传统或更有效的方法来做到这一点?
更新我意识到除了false
之外,我还想记住nil
-这可以一直追溯到https://rails.lighthouseapp.com/projects/8994/tickets/1830-railscachefetch-does-not-work-with-false-boolean-as-cached-value -我向Andrew Marshall道歉,他给出了一个完全正确的答案。
发布于 2012-06-22 23:13:40
显式检查@x_query
的值是否为nil
:
def x?
@x_query = expensive_way_to_calculate_x if @x_query.nil?
@x_query
end
请注意,如果这不是实例变量,则必须检查是否也定义了它,因为所有实例变量都默认为nil
。
如果您更新了@x_query
的memoized值可以为nil
,那么您可以使用defined?
来解决所有实例变量都默认为nil
的问题
def x?
defined?(@x_query) or @x_query = expensive_way_to_calculate_x
@x_query
end
请注意,执行像a = 42 unless defined?(a)
这样的操作不会像预期的那样工作,因为一旦解析器命中a =
,a
就会在到达条件之前定义。然而,对于实例变量就不是这样了,因为它们缺省为nil
,解析器在命中=
时不会定义它们。无论如何,我认为使用or
或unless
的长块形式而不是带有defined?
的一行unless
来保持一致性是一个很好的习惯。
发布于 2012-06-23 04:57:35
要说明nil
,请使用defined?
查看是否定义了该变量:
def x?
return @x_query if defined? @x_query
@x_query = expensive_way_to_calculate_x
end
如果未定义变量,defined?
将返回nil
,否则返回字符串"instance_variable"
:
irb(main):001:0> defined? @x
=> nil
irb(main):002:0> @x = 3
=> 3
irb(main):003:0> defined? @x
=> "instance-variable"
https://stackoverflow.com/questions/11158972
复制相似问题