在 Rails 文档中,为该方法提供的示例object.presence
是:
region = params[:state].presence || params[:country].presence || 'US'
但这不只是等同于:
region = params[:state] || params[:country] || 'US'
使用有什么意义presence
?
在 Rails 文档中,为该方法提供的示例object.presence
是:
region = params[:state].presence || params[:country].presence || 'US'
但这不只是等同于:
region = params[:state] || params[:country] || 'US'
使用有什么意义presence
?
重点是:
''.presence
# => nil
所以如果params[:state] == ''
:
region = params[:state].presence || 'US'
# => 'US'
region = params[:state] || 'US'
# => ''
nil
更重要的是,它在每个响应方法的对象上以类似的方式工作(即,如果对象为“空”则返回) empty?
,例如:
[].presence
# => nil
这是文档,供参考:
http://api.rubyonrails.org/classes/Object.html#method-i-presence
使用的真正意义#presence
在于它扩展了虚假值的概念以处理 web 和 http 场景。文档没有明确说明这个目的……而是简单地关注方法的 API:是什么而不是为什么。Web 和 HTTP 与普通编程不同,因为您通常会得到一个空字符串,而不是nil
从请求中得到的。
然而,在普通的 Ruby 中,空字符串是真值。这使得 Web 开发人员编写了许多冗余的样板代码,Object.presence
例如用作示例的文档,正如此处其他人所引用的那样。
在 Rails 中编写 Web 应用程序的人的底线是我们现在可以(应该)使用标准 Ruby 短路或#present?
, :#presence
||
# Check for a param like this
@name = params[:name].presence || 'No name given'
该行正确处理了 Web 服务器为我们打包到request
参数中的所有内容。虽然这个普通的旧红宝石没有:
# DON'T DO THIS
@name = params[:name] || 'No name given'
presence
当您想要在nil
对象不存在时返回并且在对象存在时返回对象本身时非常有用。换句话说,你想要一个看起来像这样的代码:
object.present? object : nil
您可以简单地调用object.presence
而不是上面的行,该方法将为您完成工作。
再举一个例子,presence
让我介绍一下我最喜欢的FizzBuzz解决方案:
puts 1.upto(100).map { |n| "#{'Fizz' if n%3==0}#{'Buzz' if n%5==0}".presence || n }
我只是以一种有用的方式使用它,我觉得它很整洁。我的变量是一个字符串,如果它是我想要 nil 的空字符串,否则我希望它转换为一个整数。
x.presence.try(&:to_i)
"".presence.try(&:to_i) # => nil
"22".presence.try(&:to_i) # => 22