仅仅是 "如果 "可能是不够的
if false 或者 不会执行相应的条件,因为 和 被认为是虚假的值。if nil false nil
换句话说,如果你把nil 或false 铸成布尔值,它将返回false 。所有其他类型的值在Ruby中都被认为是真实的。一个快速的破解方法(不仅适用于Ruby,也适用于JavaScript)是在变量前加一个双感叹号。
!!nil # nil => false
!!false # boolean false => false
!!true # boolean true => true
!!0 # number zero => true
!!42 # number other than zero => true
!!"" # empty string => true
!!" " # spaces-only string => true
!!"sth" # non-empty string => true
!![] # empty array => true
!![nil] # array with empty values => true
!!['a', 'z'] # non-empty array => true
!!{} # empty hash => true
!!{a: nil} # hash with empty values => true
!!{a: 42} # non-empty hash => true
!!/regex/ # regex => true
!!Time.now # any object => true
.nil? 是来自Ruby的,检查对象是否真的是nil
这是最简单的部分。在Ruby中,你可以检查一个对象是否为nil,只要在该对象上调用nil? 就可以了......即使该对象是nil。如果你想一想,这是很合乎逻辑的 :)
题外话:在Ruby中,按照惯例,每个以问号结尾的方法都被设计为返回布尔值(真或假)。在JavaScript中,惯例是不同的:通常,这种方法以 "是 "开头(isEmpty,isNumeric,等等)。
nil.nil? # nil => true
false.nil? # boolean false => false
true.nil? # boolean true => false
0.nil? # number zero => false
42.nil? # number other than zero => false
"".nil? # empty string => false
" ".nil? # spaces-only string => false
"sth".nil? # non-empty string => false
[].nil? # empty array => false
[nil].nil? # array with empty values => false
['a', 'z'].nil? # non-empty array => false
{}.nil? # empty hash => false
{a: nil}.nil? # hash with empty values => false
{a: 42}.nil? # non-empty hash => false
/regex/.nil? # regex => false
Time.now.nil? # any object => false
.empty? 是来自Ruby,它检查大小是否为0
.empty? 是一个Ruby方法,它只对Hash、Array或String有效。但不是对每个Enumerable。如果大小在0以上,它返回true。对于其他的,它返回NoMethodError。
nil.empty? # nil => NoMethodError
false.empty? # boolean false => NoMethodError
true.empty? # boolean true => NoMethodError
0.empty? # number zero => NoMethodError
42.empty? # number other than zero => NoMethodError
"".empty? # empty string => true
" ".empty? # spaces-only string => false
"sth".empty? # non-empty string => false
[].empty? # empty array => true
[nil].empty? # array with empty values => false
['a', 'z'].empty? # non-empty array => false
{}.empty? # empty hash => true
{a: nil}.empty? # hash with empty values => false
{a: 42}.empty? # non-empty hash => false
/regex/.empty? # regex => NoMethodError
Time.now.empty? # custom object => NoMethodError
.blank? 是来自ActiveSupport
.blank? 来自于奇妙的ActiveSupport。ActiveSupport是Rails的一个依赖项,所以如果你在Rails环境中,你已经有了这个方法,而且是免费的。
上面的NoMethodError ,可能会很烦人。因此,ActiveSupport添加了一个.blank? 方法,它永远不会失败。
警告:对于Rails来说,什么被认为是 "空白 "是有争议的。带有空格的字符串被认为是 "空白",但数字 "0 "则不是。请看这里的列表。
nil.blank? # nil => true
false.blank? # boolean false => true
true.blank? # boolean true => false
0.blank? # number zero => false
42.blank? # number other than zero => false
"".blank? # empty string => true
" ".blank? # spaces-only string => true
"sth".blank? # non-empty string => false
[].blank? # empty array => true
[nil].blank? # array with empty values => false
['a', 'z'].blank? # non-empty array => false
{}.blank? # empty hash => true
{a: nil}.blank? # hash with empty values => false
{a: 42}.blank? # non-empty hash => false
/regex/.blank? # regex => false
Time.now.blank? # custom object => false
没有更多的错误......但定义什么是 "空白 "的方法是有意见的。所以要特别注意。
0.blank?返回false。在我看来,0应该被认为是一个 "空白 "值。这将与其他语言更加一致。false.blank?返回true。可能会被视为奇怪或合乎逻辑,取决于你的习惯。[nil, ''].blank?返回false。空白值的数组不被认为是空白。这一次,我发现它是合乎逻辑的,因为方法 blank 评估的是数组,而不是数组里面的东西。- 现在棘手的部分是:
[nil].any?返回false。但是[''].any?却返回真。这是因为空字符串是真实的。如果你想检查[nil, '']是否包含任何有趣的东西,你可以这样做:[nil, ''].all?(&:blank?)返回真。
.present? 也来自ActiveSupport
.present? 是空白的否定,所以在这里并不奇怪。
nil.present? # nil => false
false.present? # boolean false => false
true.present? # boolean true => true
0.present? # number zero => true
42.present? # number other than zero => true
"".present? # empty string => false
" ".present? # spaces-only string => false
"sth".present? # non-empty string => false
[].present? # empty array => false
[nil].present? # array with empty values => true
['a', 'z'].present? # non-empty array => true
{}.present? # empty hash => false
{a: nil}.present? # hash with empty values => true
{a: 42}.present? # non-empty hash => true
/regex/.present? # regex => true
Time.now.present? # custom object => true
结论
作为备忘,我把这个决策表放在这里。
| 方法 | 如果() | nil? | 空? | 任何? | 空白? | present?(!blank?) |
|---|---|---|---|---|---|---|
| 范围 | 红宝石 | 仅限rails | ||||
| 对象 | 所有 | 字符串、数组、哈希 | 可列举 | 全部 | ||
| nil | 错误 | true | 无方法错误 | NoMethodError | true | 错误 |
| 错误 | 虚假 | 错误 | 无方法错误 | 无方法错误(NoMethodError | 准确的 | 错误 |
| true | true | 错误 | 无方法错误(NoMethodError | NoMethodError | 错误 | true |
| 0 | true | 错误 | 无方法错误(NoMethodError | 无方法错误(NoMethodError | 错误 | true |
| 42 | true | 错误 | 无方法错误(NoMethodError | 无方法错误(NoMethodError | 错误 | true |
| "" | true | 错误 | true | 无方法错误(NoMethodError | true | 错误 |
| "" | true | 虚假 | 虚假 | 无方法错误(NoMethodError | true | 错误 |
| "..." | true | 错误 | 错误 | 无方法错误(NoMethodError | 错误 | true |
| [] | true | 错误 | 真 | 虚假 | 真 | 假的 |
| [无] | 真 | 虚假 | 虚假 | 虚假 | 虚假 | 真 |
| ['a', 'z'] | 真 | 假的 | 错误 | 真 | 虚假 | 真 |
| {} | true | 假的 | 真 | 虚假 | 真 | 假的 |
| { a: nil } | 真 | 假的 | 假的 | 真 | 虚假 | 真 |
| { a:42 } | 真 | 假的 | 假的 | 真 | 虚假 | 真 |
| /regex/ | 真 | false | 方法错误(NoMethodError | NoMethodError | 错误 | true |
| 时间.现在 | true | false | 方法错误(NoMethodError | 无方法错误(NoMethodError | false | true |