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

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

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

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

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

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

19.05.2009 22:51:36
Одна ошибка - пустой массив, возвращает false для present?. Это потому, что blank?возвращает true для пустого массива.
Kris 25.04.2012 10:41:22
Одна хорошая вещь , чтобы увидеть , что :nil?определяется на ::Kernelи переопределена ::NilClass, в то время как :empty?осуществляется отдельно от многих классов (изначально на ::String, ::Array, ::Hash, и не родной на других классах , как ::Setот STDLIB и ::ActiveRecord::Relationот рельсов). Так :nil?доступно во всех подклассах, ::Objectа также в каждом классе, который включает ::Kernelсам по себе, где :empty?должны быть реализованы или включены конкретно в ваши классы.
rewritten 22.03.2016 10:00:10
Если вы пытаетесь понять всю nilконцепцию, начните здесь .
totymedli 13.06.2018 18:07:24
[1] pry(main)> [].blank? => true
Michael 23.03.2019 03:46:15
14 ОТВЕТОВ
РЕШЕНИЕ

.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 
1430
6.10.2015 11:39:24
Как уже упоминалось в вопросе, некоторые непустые строки считаются пустыми.
Andrew Grimm 20.05.2009 23:20:55
Почему они не перезаписывают ноль .empty? если бы они могли добавить .blank?
tillda 2.03.2011 23:01:14
Также:false.blank? == true
Shannon 5.11.2012 18:02:42
Я бы упомянул presence!
Marc-André Lafortune 3.04.2013 02:12:40
В дополнение к тому, что Том упоминает в своем ответе на вопрос о пустом массиве, следует помнить, что это может привести к проблемам с безопасностью, когда злоумышленник может использовать неподготовленный код, который просто проверяет разве что params.nil? или разве что params.blank? и является причиной большого обсуждения и работы в настоящее время в Rails. Смотрите здесь для получения дополнительной информации: github.com/rails/rails/issues/13420
Houen 30.07.2014 15:54:08

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

51
14.11.2012 14:53:41

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

12
19.05.2009 23:51:50
.Любые? не работает со строками в ruby ​​1.9, как .any? требует перечисления, и строка # каждая не работает в ruby ​​1.9.
Andrew Grimm 20.05.2009 00:59:54
Осторожно any?для проверки не пустоты. Он возвращает false, если у вас есть массив ложных значений. Способ обойти это - пропустить всегда истинный блок:, [nil, false].any?{ true }но !empty?он короче, и вы не помните странного поведения.
Kelvin 1.05.2013 19:30:08

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

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

13
13.07.2009 19:25:16
В Rails любая строка, содержащая только пробельные символы, является «пустой»: «\ n \ r \ t» .blank? # => правда
Lonny Eachus 20.02.2014 23:17:33

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

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

62
13.07.2010 11:33:23
есть что-то эквивалентное! obj.nil?
Kirk 20.09.2012 21:27:17
present?является частью active_support, проверьте здесь, что включить, чтобы получить его: stackoverflow.com/a/4648704/1569
Factor Mystic 19.02.2013 20:56:19
@Kirk: !! obj эквивалентно! Obj.nil?
Mohamed Hafez 3.12.2013 20:34:16
@ MohamedHafez Нет, это не так. !!false
Ajedi32 21.03.2014 18:02:50
Ах, @ Ajedi32 хороший улов! эквивалентно этому единственному исключению.
Mohamed Hafez 21.03.2014 22:14:23

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

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

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

15
14.11.2012 13:56:02

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

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

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

671
12.08.2018 16:19:17
Стоит отметить, что пустым? а присутствует? только для Rails. Они возвращают исключение: NoMethodError в Ruby 2.0.0.
Lonny Eachus 20.02.2014 23:27:55
Попробуйте добавить, any?если вы когда-нибудь обновите таблицу.
Dennis 5.09.2014 17:07:14
blank?и present?они не « только для Rails », они автоматически включаются Rails, но могут быть легко включены в не-Rails-код с помощью расширений Core ActiveSupport. См. Stackoverflow.com/questions/4238867/…
the Tin Man 28.01.2020 18:16:52

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

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

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

214
4.09.2016 14:09:37
@ Сибевин Ван, я скачал эту таблицу и использовал ее в некоторых своих ответах, добавив тебе кредиты. Надеюсь, вы не будете возражать :) Престижность этого большого усилия!
Lahiru 21.07.2016 06:06:41
Enumerable#any?ванильный рубин, его не следует указывать под
daniero 4.09.2016 12:30:41
@daniero Спасибо за напоминание, таблица обновлена.
Sibevin Wang 4.09.2016 14:06:42
Числовые типы также имеют .zero?и.nonzero?
DaveMongoose 9.01.2017 11:36:56

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как для объектов, так и для пустых объектов.

11
29.01.2016 18:27:21

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

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

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

6
29.01.2016 18:25:33

Рельсы 4

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

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

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

[nil, '', "", " ",'  '].reject(&:blank?).blank? == true
3
19.08.2015 13:52:27

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

2
29.01.2016 18:23:46

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

4
18.02.2016 19:05:37
Работает только на модельном классе!
Roger 9.12.2016 22:00:39

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

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

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

45
15.01.2018 18:17:51
во! Вы получили мой +1
Am33d 1.08.2018 06:11:55