Как понять ноль против пустого или пустого в Ruby

1129

Я считаю себя постоянно ищу четкое определение различий nil?, blank?и empty?в Ruby On Rails. Вот самый близкий я пришел:

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

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

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

Чего не хватает, или можно сделать более жесткое сравнение?

Arrel
источник
26
Одна ошибка - пустой массив, возвращает false для present?. Это потому, что blank?возвращает true для пустого массива.
Крис
4
Одна хорошая вещь , чтобы увидеть , что :nil?определяется на ::Kernelи переопределена ::NilClass, в то время как :empty?осуществляется отдельно от многих классов (изначально на ::String, ::Array, ::Hash, и не родной на других классах , как ::Setот STDLIB и ::ActiveRecord::Relationот рельсов). Так :nil?доступно во всех подклассах, ::Objectа также в каждом классе, который включает ::Kernelсам по себе, где :empty?должны быть реализованы или включены конкретно в ваши классы.
переписано
Если вы пытаетесь понять всю nilконцепцию, начните здесь .
Тотимедли
[1] pry(main)> [].blank? => true
Майкл

Ответы:

1437

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

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

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

Бег .empty?на что-то, что ноль, бросит 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?.

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

[ nil, '' ].blank? == false
[ nil, '' ].all? &:blank? == true 
Корбан Брук
источник
27
Как уже упоминалось в вопросе, некоторые непустые строки считаются пустыми.
Эндрю Гримм
1
Почему они не перезаписывают ноль .empty? если бы они могли добавить .blank?
до
6
Также:false.blank? == true
Шеннон
2
Я бы упомянул presence!
Марк-Андре Лафортун
2
В дополнение к тому, что Том упоминает в своем ответе о пустых массивах, помните, что это может привести к проблемам с безопасностью, когда злоумышленник может использовать неподготовленный код, который просто проверяет разве что params.nil? или, если не params.blank ?, и является причиной большого обсуждения и работы в настоящее время в Rails. Смотрите здесь для получения дополнительной информации: github.com/rails/rails/issues/13420
Houen
675

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

введите описание изображения здесь

blank?, present?предоставляются Rails.

Юлиан Попов
источник
57
Стоит отметить, что пустым? а присутствует? только для Rails. Они возвращают исключение: NoMethodError в Ruby 2.0.0.
Lonny Eachus
17
Рассмотрите возможность добавления, any?если вы когда-нибудь обновите таблицу.
Деннис
blank?и present?они не « только для Rails », они автоматически включаются Rails, но могут быть легко включены в не-Rails-код с помощью расширений Core ActiveSupport. См. Stackoverflow.com/questions/4238867/…
Жестянщик
215

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

введите описание изображения здесь

Ссылка: пусто? Пусто? Ноль? 傻傻 分不清楚

Сибевин Ван
источник
1
@ Сибевин Ван, я скачал эту таблицу и использовал ее в некоторых своих ответах, добавляя тебе кредиты. Надеюсь, вы не будете возражать :) Престижность этого большого усилия!
Лахиру
1
Enumerable#any?ванильный рубин, его не следует указывать под
заголовком
1
@daniero Спасибо за напоминание, таблица обновлена.
Сибевин Ван
Числовые типы также имеют .zero?и.nonzero?
DaveMongoose
63

Быстрая подсказка: !obj.blank? == obj.present?

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

Александр Малфей
источник
есть что-то эквивалентное! obj.nil?
Кирк
present?является частью active_support, проверьте здесь, что включить, чтобы получить его: stackoverflow.com/a/4648704/1569
Factor Mystic
2
@Kirk: !! obj эквивалентно! Obj.nil?
Мохамед Хафез
4
@ MohamedHafez Нет, это не так. !!false
Ajedi32
Ах, @ Ajedi32 хороший улов! эквивалентно этому единственному исключению.
Мохамед Хафез
52

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

Эндрю Гримм
источник
49

введите описание изображения здесь

  • Все что nil?естьblank?
  • Все что empty?естьblank?
  • Ничего, что empty?естьnil?
  • Ничего, что nil?естьempty?

tl; dr - используйте только blank?&, present?если вы не хотите различать ""и" "

Стив
источник
2
во! Вы получили мой +1
Am33d
16

Особый случай - при попытке оценить, является ли логическое значение нулевым:

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

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

Алан Х
источник
14

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

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

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

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


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

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

b = nil
b.nil? # => true

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

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

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

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

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

неха
источник
7

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

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

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

Маниш Шривастава
источник
5

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

кельвин
источник
Работает только на модельном классе!
Роджер
4

Рельсы 4

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

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

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

[nil, '', "", " ",' '].reject(&:blank?).blank? == true
mahatmanich
источник
3

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?это полезно для проверки объектов, которые вы считаете коллекциями, но они также могут быть нулевыми.

Читра
источник