首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何记忆Ruby中可能返回true、false或nil的方法?

如何记忆Ruby中可能返回true、false或nil的方法?
EN

Stack Overflow用户
提问于 2012-06-22 23:09:30
回答 2查看 5K关注 0票数 16

显然,||=不会工作

代码语言:javascript
复制
def x?
  @x_query ||= expensive_way_to_calculate_x
end

因为如果结果是falsenil,那么expensive_way_to_calculate_x就会一遍又一遍地运行。

目前,我所知道的最好的方法是将值放入Array

代码语言:javascript
复制
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道歉,他给出了一个完全正确的答案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-22 23:13:40

显式检查@x_query的值是否为nil

代码语言:javascript
复制
def x?
  @x_query = expensive_way_to_calculate_x if @x_query.nil?
  @x_query
end

请注意,如果这不是实例变量,则必须检查是否也定义了它,因为所有实例变量都默认为nil

如果您更新了@x_query的memoized值可以为nil,那么您可以使用defined?来解决所有实例变量都默认为nil的问题

代码语言:javascript
复制
def x?
  defined?(@x_query) or @x_query = expensive_way_to_calculate_x
  @x_query
end

请注意,执行像a = 42 unless defined?(a)这样的操作不会像预期的那样工作,因为一旦解析器命中a =a就会在到达条件之前定义。然而,对于实例变量就不是这样了,因为它们缺省为nil,解析器在命中=时不会定义它们。无论如何,我认为使用orunless的长块形式而不是带有defined?的一行unless来保持一致性是一个很好的习惯。

票数 29
EN

Stack Overflow用户

发布于 2012-06-23 04:57:35

要说明nil,请使用defined?查看是否定义了该变量:

代码语言:javascript
复制
def x?
  return @x_query if defined? @x_query
  @x_query = expensive_way_to_calculate_x
end

如果未定义变量,defined?将返回nil,否则返回字符串"instance_variable"

代码语言:javascript
复制
irb(main):001:0> defined? @x
=> nil
irb(main):002:0> @x = 3
=> 3
irb(main):003:0> defined? @x
=> "instance-variable"
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11158972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档