`!!empty?`的含义是什么?

3

ActiveSupport将Object扩展为具有实例方法blank?

class Object
  def blank?
    respond_to?(:empty?) ? !!empty? : !self
  end
end
< p > “!!empty?”可以改写成“empty?”吗?这是一种风格选择,使其易于阅读为返回布尔值的方法吗?还是有其他原因?


我想你应该认识到这个操作行与 self.respond_to?(:empty?)? !!self.empty? : !self 是一样的吧?我不明白为什么需要 !!,因为 empty? 已经返回了一个布尔值。 - Cary Swoveland
阅读代码并澄清任何疑问做得很好。这是学习新语言的好方法。 - Leonel Galán
我重新打开了这个问题,因为它有点不同。原帖的作者特别询问为什么在谓词方法应该返回布尔值的情况下需要使用 !! - Stefan
5个回答

6
这是因为!!将响应从空转换为布尔值。在不同的对象上,空可能有不同的定义,因此在rails中,某人可能已经定义了.empty?以不返回布尔值。由于.blank?需要返回布尔值,因此需要使用!!来确保返回布尔值。

4

将一个“truthy”或“falsy”值转换为严格的truefalse是一种常见的方法。


3

在Ruby中,经常用!!(something)的方式来调用方法。计算结果将会是布尔值,而不是nil或其他类型:

!!(true) # true
!!(false) # false
!!(nil) # false

2

!!用于将假值/真值强制转换为false/true:

irb(main):001:0> !!nil == false
=> true

2
事实上,它曾经是empty?。这是更改为!!empty?的提交:https://github.com/rails/rails/commit/126dc47665c65cd129967cbd8a5926dddd0aa514评论中可以看出: :为什么要双重使用!!?它无论如何都会返回TrueClass/FalseClass :因为它是一种动态语言,受到多态性的影响,你不能只依赖于empty?返回单例,你需要保证无论如何都返回一个。
然而,“改进”的实现是不完整的,因为您同样可以实现!来返回非布尔值:
class Foo
  def !
    nil
  end
end

Foo.new.blank? #=> nil

为了处理empty?!这两种方法,应该实现为:

!!(respond_to?(:empty?) ? empty? : !self)

您还应该在 GitHub 页面上发布评论。 - Cary Swoveland
@CarySwoveland 你说得对,我已经发起了一个拉取请求。 - Stefan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接