如何在 Ruby 中理解 nil vs. empty vs. blank

How to understand nil vs. empty vs. blank in Ruby

提问人:Arrel 提问时间:5/20/2009 最后编辑:the Tin ManArrel 更新时间:5/17/2023 访问量:330731

问:

我发现自己在 Ruby on Rails 中反复寻找 、 和 的区别的明确定义。这是我最接近的:nil?blank?empty?

  • blank?对象为 false、空或空格字符串。例如,、、、和为空。""" "nil[]{}

  • nil?对象是 NilClass 的实例。

  • empty?对象是特定于类的,并且定义因类而异。如果字符串没有字符,则字符串为空,如果数组不包含任何项,则为空。

是否遗漏了什么,或者可以进行更紧密的比较?

Ruby-on-Rails 红宝石

评论

30赞 Kris 4/25/2012
一个问题是空数组返回 false 。这是因为对于空数组返回 true。present?blank?
4赞 rewritten 3/22/2016
一件好事是看到它在 上定义和覆盖,同时在许多类上单独实现(原生在 、 、 和 等其他类上非原生实现,例如 stdlib 和 rails)。因此,在它本身包含的每个子类中都可用,其中必须实现或专门包含在您的类中。:nil?::Kernel::NilClass:empty?::String::Array::Hash::Set::ActiveRecord::Relation:nil?::Object::Kernel:empty?
0赞 totymedli 6/14/2018
如果您尝试理解整个概念,请从这里开始nil
0赞 Michael 3/23/2019
[1] pry(main)> [].blank? => true

答:

57赞 Andrew Grimm 5/20/2009 #1

一个区别是 和 是由编程语言 Ruby 提供的方法,而是由 Web 开发框架 Rails 添加的方法。.nil?.empty?.blank?

15赞 Andy 5/20/2009 #2

别忘了哪个一般是.在 Rails 中,我通常会检查语句末尾是否存在某些内容,然后在需要时使用,因为它似乎在任何地方都有效。any?!empty?if somethingunless somethingblank?

评论

4赞 Andrew Grimm 5/20/2009
。任何?不适用于 Ruby 1.9 中的字符串,如 .any?需要 enumerable,而 string#each 本身在 Ruby 1.9 中不起作用。
4赞 Kelvin 5/2/2013
注意检查非空性。如果您有一个虚假值数组,则返回 false。解决这个问题的一种方法是传递一个始终为真的块:,但更短,你不记得奇怪的行为。any?[nil, false].any?{ true }!empty?
1493赞 Corban Brook 5/21/2009 #3

.nil?可以在任何对象上使用,如果对象为 nil,则为 true。

.empty?可用于字符串、数组和哈希,如果出现以下情况,则返回 true:

  • 字符串长度 == 0
  • 数组长度 == 0
  • 哈希长度 == 0

在 nil 的东西上运行会抛出一个 ..empty?NoMethodError

这就是用武之地。它由 Rails 实现,可以对任何对象进行操作,也可以像对字符串、数组和哈希值一样工作。.blank?.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?

数组陷阱:即使数组的所有元素都为空,也会返回。在这种情况下,要确定空白度,请使用 ,例如:blank?falseall?blank?

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

评论

28赞 Andrew Grimm 5/21/2009
如问题中所述,一些非空字符串计为空白。
1赞 tillda 3/3/2011
为什么他们没有覆盖 nil 的 .empty?如果他们可以添加 .blank?
7赞 Shannon 11/6/2012
也:false.blank? == true
1赞 TrinitronX 4/10/2013
我以前见过在非 rails 上下文中错误地使用。如果你真的需要它,你可以包括它blank?require 'active_support/core_ext/object/blank'
2赞 Houen 7/30/2014
作为 Tom 在他的回答中提到的全空白数组陷阱的补充,请注意,这可能会导致安全问题,攻击者可以使用未准备好的代码来检查除非 params.nil?或者除非 params.blank?,并且是目前 Rails 中许多讨论和工作的原因。有关详细信息,请参阅此处:github.com/rails/rails/issues/13420
16赞 davemyron 7/14/2009 #4

关于建议的一点说明:他是对的,它通常等同于 .但是,将返回到一个只有空格的字符串 (ala )。any?!empty?any?true" "

当然,也可以查看上面的 1.9 评论。

评论

0赞 Lonny Eachus 2/21/2014
在 Rails 中,任何只包含空格字符的字符串都是 “blank”: “ \n\r\t”.blank?#=> 真
66赞 Alexander Malfait 7/13/2010 #5

小贴士:!obj.blank? == obj.present?

在某些表情中可以方便/更容易对眼睛

评论

0赞 Kirk 9/21/2012
有没有等同于 !obj.nil 的东西?
0赞 Factor Mystic 2/20/2013
present?是active_support的一部分,请在此处查看要包含的内容以获取它: stackoverflow.com/a/4648704/1569
2赞 Mohamed Hafez 12/4/2013
@Kirk:!!obj 等同于 !obj.nil?
4赞 Ajedi32 3/22/2014
@MohamedHafez 不,不是。!!false
0赞 Mohamed Hafez 3/22/2014
啊,@Ajedi32好渔获!等同于那个例外。
18赞 Alan H 11/14/2012 #6

一种特殊情况是尝试评估布尔值是否为 nil:

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

在这种情况下,建议使用.nil?

712赞 Julian Popov 12/19/2013 #7

我用所有的情况制作了这个有用的表格:

enter image description here

blank?,由 Rails 提供。present?

评论

58赞 Lonny Eachus 2/21/2014
需要注意的是,空白?现在呢?仅限 Rails。它们在 Ruby 2.0.0 中返回 Exception: NoMethodError。
17赞 Dennis 9/6/2014
如果您曾经更新过表,请考虑添加。any?
0赞 the Tin Man 1/29/2020
blank?并且不是“仅限 Rails”,它们会自动包含在 Rails 中,但可以通过使用 ActiveSupport 的核心扩展轻松包含在非 Rails 代码中。请参阅 stackoverflow.com/questions/4238867/...present?
230赞 Sibevin Wang 11/12/2014 #8

只需扩展 Julian 的表:

enter image description here

Ref: empty?blank?nil?傻傻分不清楚

评论

1赞 Lahiru Jayaratne 7/21/2016
@Sibevin Wang,我已经下载了这张表,并在我的一些答案中使用它,将学分添加到您身上。希望你不会介意:)为这一巨大努力点赞!
2赞 daniero 9/4/2016
Enumerable#any?是香草 Ruby,它不应该列在“仅限 rails”下
1赞 Sibevin Wang 9/4/2016
@daniero 感谢您的提醒,表格已更新。
1赞 DaveMongoose 1/9/2017
数值类型还具有 和.zero?.nonzero?
14赞 neha 12/22/2014 #9

nil?是一个标准的 Ruby 方法,可以在所有对象上调用,如果对象是:truenil

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

9赞 Manish Shrivastava 5/20/2015 #10

其他人都很好地解释了有什么区别。

我想在Ruby On Rails中添加,最好使用or代替或。obj.blank?obj.present?obj.nil?obj.empty?

obj.blank?处理所有类型 、 、 、 ,如果值不可用,则返回,如果值在任何类型的对象上可用,则返回。nil''[]{}truefalse

6赞 mahatmanich 8/19/2015 #11

轨道 4

@corban-brook 的“数组 gotcha: blank?”的替代方案,用于检查数组是否只包含空值并且可以被视为空白?真:

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

也可以这样做:

[nil, '', "", " ",' '].reject(&:blank?).blank? == true
5赞 Chitra 9/15/2015 #12

nil?可用于任何对象。它确定对象是否具有任何值,包括“空白”值。

例如:

example = nil
example.nil?  # true

"".nil?  # false

基本上,只有当对象实际上等于“nil”时,才会返回 true。nil?

empty?仅在被视为集合的对象上调用。这包括字符串(字符的集合)、哈希(键/值对的集合)和数组(任意对象的集合)等内容。 如果集合中没有项,则返回 true。empty?

例如:

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

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

请注意,不能对 nil 对象进行调用,因为 nil 对象不是集合,并且会引发异常。empty?

另请注意,即使集合中的项为空,也不意味着集合为空。

blank?基本上是 和 的组合 它对于检查您认为是集合但也可能为 nil 的对象很有用。nil?empty?

7赞 kelvin 2/17/2016 #13

exists?方法可用于检查数据库中是否存在数据。它返回布尔值 either 或 .truefalse

评论

0赞 Roger 12/10/2016
仅适用于模型类!
59赞 steve 1/16/2018 #14

enter image description here

  • 一切都是nil?blank?
  • 一切都是empty?blank?
  • 什么都不是empty?nil?
  • 什么都不是nil?empty?

tl;dr -- 只使用 &,除非你想区分 和blank?present?""" "

8赞 shahjapan 3/12/2021 #15

虽然这个问题有 n 个答案,但我喜欢这里解释它的方式,所以又发布了一个答案:-)

看看下面的数据指标 - 它不言自明,在可用方法中使用的各种数据类型。

#nil? #empty? #blank? #present?
5 NoMethodError
""
" "
“\t\n”
[]
[“a”]
{}
{a: “b”}
Set.new
NoMethodError
NoMethodError
NoMethodError

参考: https://blog.appsignal.com/2018/09/11/differences-between-nil-empty-blank-and-present.html