Краткое объяснение nil v. Empty v. Blank в Ruby on Rails

833

Я постоянно искал четкое определение различий в nil?, blank? и empty? в Ruby on Rails. Вот ближайший я пришел:

  • blank? объекты являются ложными, пустыми или пробельными строками. Например, "", " ", nil, [] и {} пусты.

  • nil? объекты являются экземплярами NilClass.

  • empty? объекты относятся к классу, и определение варьируется от класса к классу. Строка пуста, если она не имеет символов, а массив пуст, если не содержит элементов.

Есть ли что-то недостающее или более точное сравнение, которое можно сделать?

  • 23
    Один гоча пустой массив возвращает false для present? , Что потому, что blank? возвращает true для пустого массива.
  • 4
    Приятно видеть это :nil? определяется на ::Kernel и переопределяется на ::NilClass , тогда как :empty? реализован отдельно во многих классах (изначально для ::String , ::Array , ::Hash и не для других классов, таких как ::Set from stdlib и ::ActiveRecord::Relation from rails). Итак :nil? доступно во всех подклассах ::Object а также в каждом классе, который включает ::Kernel сам по себе, где :empty? должны быть реализованы или включены конкретно в ваши классы.
Показать ещё 2 комментария
Теги:

13 ответов

1129
Лучший ответ

.nil? может использоваться для любого объекта и является истинным, если объект равен нулю.

.empty? может использоваться для строк, массивов и хэшей и возвращает true, если:

  • Длина строки == 0
  • Длина массива == 0
  • Длина хеша == 0

Запуск .empty? на то, что является nil, будет бросать NoMethodError.

Здесь приходит .blank?. реализованный Rails и будет работать на любом объекте, а также работать как .empty? на строках, массивах и хешах.

nil.blank? == true
false.blank? == true
[].blank? == true
{}.blank? == true
"".blank? == true
5.blank? == false
0.blank? == false

.blank? также оценивает значение true для строк, которые не являются пустыми, но содержат только пробелы:

"  ".blank? == true
"  ".empty? == false

Rails также предоставляет .present?, который возвращает отрицание .blank?.

Массив getcha: blank? вернет false, даже если все элементы массива пустые. Чтобы определить пустоту в этом случае, используйте all? с blank?, например:

[ nil, '' ].blank? == false
[ nil, '' ].all? &:blank? == true 
  • 25
    Как уже упоминалось в вопросе, некоторые непустые строки считаются пустыми.
  • 1
    Почему они не перезаписывают ноль .empty? если бы они могли добавить .blank?
Показать ещё 10 комментариев
544

Я сделал эту полезную таблицу со всеми случаями:

Изображение 4147

  • 51
    Следует отметить, что пустым? а присутствует? только для Rails. Они возвращают исключение: NoMethodError в Ruby 2.0.0.
  • 15
    Рассмотрите возможность добавления any? если вы когда-нибудь обновите таблицу.
Показать ещё 1 комментарий
134

Просто растяните таблицу Джулиана:

Изображение 4148

Ссылка: empty? blank? nil? 傻傻 分不清楚

  • 1
    @ Сибевин Ван, я скачал эту таблицу и использовал ее в некоторых своих ответах, добавляя тебе кредиты. Надеюсь, вы не будете возражать :) Престижность этого большого усилия!
  • 0
    Enumerable#any? ванильный рубин, его не следует перечислять в разделе «только рельсы»
Показать ещё 4 комментария
54

Быстрый совет: !obj.blank? == obj.present?

Может быть удобнее/проще на глазах в некоторых выражениях

  • 0
    есть что-то эквивалентное! obj.nil?
  • 0
    present? является частью active_support, проверьте здесь, что включить, чтобы получить его: stackoverflow.com/a/4648704/1569
Показать ещё 4 комментария
43

Одно отличие состоит в том, что .nil? и .empty? - это методы, которые предоставляются языком программирования Ruby, тогда как .blank? - это что-то добавлено с помощью среды разработки Rails.

8

Небольшая заметка о рекомендации any?: он прав, что он обычно эквивалентен !empty?. Однако any? возвращает true в строку только пробела (ala " ").

И, конечно, см. также комментарий выше 1.9.

  • 0
    В Rails любая строка, содержащая только пробельные символы, является «пустой»: «\ n \ r \ t» .blank? # => правда
7

Частным случаем является попытка оценить, является ли логическое значение равным nil:

false.present? == false
false.blank? == true
false.nil? == false

В этом случае рекомендуется использовать .nil?

7

Не забывайте any?, который обычно !empty?. В Rails я обычно проверяю наличие чего-либо в конце инструкции с помощью if something или unless something, а затем используйте blank? там, где это необходимо, так как он работает повсюду.

  • 4
    .любой? не работает со строками в ruby 1.9, как .any? требует перечисления, и строка # каждая не работает в ruby 1.9.
  • 4
    Осторожнее any? для проверки не пустоты. Он возвращает false, если у вас есть массив ложных значений. Чтобы обойти это, нужно передать блок, который всегда истинен: [nil, false].any?{ true } , но !empty? короче, и вы не помните странное поведение.
6

nil? - стандартный метод Ruby, который можно вызвать для всех объектов и возвращает true, если объект nil:

b = nil
b.nil? # => true

empty? - стандартный метод Ruby, который может быть вызван для некоторых объектов, таких как строки, массивы и хэши, и возвращает true, если эти объекты не содержат элемента:

a = []
a.empty? # => true

b = ["2","4"]
b.empty? # => false

empty? не может быть вызван на объекты nil.

blank? - это метод Rails, который можно вызывать на объектах nil, а также пустых объектах.

2

exists? метод может использоваться для проверки наличия данных в базе данных или нет. Он возвращает логические значения либо true, либо false.

  • 0
    Работает только на модельном классе!
1

nil? может использоваться на любом объекте. Он определяет, имеет ли объект какое-либо значение или нет, включая "пустые" значения.

Например:

example = nil
example.nil?  # true

"".nil?  # false

В основном nil? будет возвращаться только true, если объект фактически равен "nil".

empty? вызывается только для объектов, которые считаются коллекцией. Сюда входят такие вещи, как строки (набор символов), хеши (набор пар ключ/значение) и массивы (совокупность произвольных объектов). empty? возвращает true, нет элементов в коллекции.

Например:

"".empty? # true
"hi".empty?   # false
{}.empty?  # true
{"" => ""}.empty?   # false
[].empty?   # true
[nil].empty?  # false

nil.empty?  # NoMethodError: undefined method `empty?' for nil:NilClass

Обратите внимание, что empty? нельзя вызывать на nil-объектах, поскольку объекты nil не являются коллекцией, и это приведет к возникновению исключения.

Также обратите внимание, что даже если элементы в коллекции пустые, это не означает, что коллекция пуста.

blank? - это в основном комбинация nil? и empty?. Она полезна для проверки объектов, которые вы считаете коллекциями, но также может быть nil.

1

Рельсы 4

альтернатива @corban-brook 'Array gotcha: blank?' для проверки, содержит ли массивы только пустые значения и может считаться пустой? верно:

[ nil, '' ].all? &:blank? == true

можно также сделать:

[nil, '', "", " ",'  '].reject(&:blank?).blank? == true
1

Все остальные хорошо объяснили, в чем разница.

Я хотел бы добавить Ruby On Rails, лучше использовать obj.blank? или obj.present? вместо obj.nil? или obj.empty?.

obj.blank? обрабатывает все типы nil, '', [], {} и возвращает true, если значения недоступны и возвращает false, если значения доступны для любого типа объекта.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню