Что означает `!!empty?`?

ActiveSupport расширяется Object с методом экземпляра blank?:

class Object
  def blank?
    respond_to?(:empty?) ? !!empty? : !self
  end
end

Мог !!empty? быть написано как empty? вместо? Это стилистический выбор, так что он легко читается как метод, возвращающий логическое значение? Или есть что-то еще?

5 ответов

Решение

Причина этого в том, что !! Приводит ответ от пустого к логическому. Пустой может быть определен по-разному на разных объектах, поэтому возможно, что кто-то в рельсах мог определить .empty? не возвращать логическое значение. поскольку .blank? необходимо вернуть логическое значение !! необходимо, чтобы гарантировать, что логическое значение возвращается.

Это общепринятый способ преобразования истинного и ложного значения в строгое true а также false,

Это общий подход в Ruby для вызова !!(something), Результат вычисления будет логическим, а не ноль или что-то еще:

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

!! используется для принудительного задания значений false /truey в false/true:

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

На самом деле, это было empty?, Вот коммит, который изменил его на !!empty?: https://github.com/rails/rails/commit/126dc47665c65cd129967cbd8a5926dddd0aa514

Из комментариев:

Bartuz:
Почему двойной !!? Возвращает TrueClass / FalseClass anynway

FXN:
Поскольку это динамический язык и подвержен полиморфизму, вы просто не можете полагаться на empty? возвращая синглтоны, вам нужно гарантировать, что вы вернете один, несмотря ни на что.

"Улучшенная" реализация, однако, неполна, потому что вы могли бы также реализовать ! вернуть не булево значение:

class Foo
  def !
    nil
  end
end

Foo.new.blank? #=> nil

Для обработки обоих методов (empty? а также !), это должно быть реализовано как:

!!(respond_to?(:empty?) ? empty? : !self)
Другие вопросы по тегам