Skip to content

Commit 126dc47

Browse files
committed
blank? and present? commit to return singletons [Xavier Noria & Pavel Pravosud]
The contract of blank? and present? was in principle to return Object, as we generally do, the test suite and description was consistent with that, but some examples had comments like "# => true". This cannot be unclear, we either fix the examples, or update the contract. Since users may be already assuming singletons due to the examples and the fact that they were returned before 30ba7ee, the safest option seems to be to revise the contract and the implementation of String#blank? The motivation for 30ba7ee was to improve the performance of the predicate, the refactor based on === is on par regarding speed. With this commit we start documenting return types using YARD conventions. We plan to document return types gradually.
1 parent 7b89446 commit 126dc47

3 files changed

Lines changed: 57 additions & 25 deletions

File tree

activesupport/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* `blank?` and `present?` commit to return singletons.
2+
3+
*Xavier Noria*, *Pavel Pravosud*
4+
15
* Fixed Float related error in NumberHelper with large precisions.
26

37
before:

activesupport/lib/active_support/core_ext/object/blank.rb

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,42 @@ class Object
44
# An object is blank if it's false, empty, or a whitespace string.
55
# For example, '', ' ', +nil+, [], and {} are all blank.
66
#
7-
# This simplifies:
7+
# This simplifies
88
#
9-
# if address.nil? || address.empty?
9+
# address.nil? || address.empty?
1010
#
11-
# ...to:
11+
# to
1212
#
13-
# if address.blank?
13+
# address.blank?
14+
#
15+
# @return [true, false]
1416
def blank?
15-
respond_to?(:empty?) ? empty? : !self
17+
respond_to?(:empty?) ? !!empty? : !self
1618
end
1719

18-
# An object is present if it's not <tt>blank?</tt>.
20+
# An object is present if it's not blank.
21+
#
22+
# @return [true, false]
1923
def present?
2024
!blank?
2125
end
2226

23-
# Returns object if it's <tt>present?</tt> otherwise returns +nil+.
24-
# <tt>object.presence</tt> is equivalent to <tt>object.present? ? object : nil</tt>.
27+
# Returns the receiver if it's present otherwise returns +nil+.
28+
# <tt>object.presence</tt> is equivalent to
2529
#
26-
# This is handy for any representation of objects where blank is the same
27-
# as not present at all. For example, this simplifies a common check for
28-
# HTTP POST/query parameters:
30+
# object.present? ? object : nil
31+
#
32+
# For example, something like
2933
#
3034
# state = params[:state] if params[:state].present?
3135
# country = params[:country] if params[:country].present?
3236
# region = state || country || 'US'
3337
#
34-
# ...becomes:
38+
# becomes
3539
#
3640
# region = params[:state].presence || params[:country].presence || 'US'
41+
#
42+
# @return [Object]
3743
def presence
3844
self if present?
3945
end
@@ -43,6 +49,8 @@ class NilClass
4349
# +nil+ is blank:
4450
#
4551
# nil.blank? # => true
52+
#
53+
# @return [true]
4654
def blank?
4755
true
4856
end
@@ -52,6 +60,8 @@ class FalseClass
5260
# +false+ is blank:
5361
#
5462
# false.blank? # => true
63+
#
64+
# @return [true]
5565
def blank?
5666
true
5767
end
@@ -61,6 +71,8 @@ class TrueClass
6171
# +true+ is not blank:
6272
#
6373
# true.blank? # => false
74+
#
75+
# @return [false]
6476
def blank?
6577
false
6678
end
@@ -71,6 +83,8 @@ class Array
7183
#
7284
# [].blank? # => true
7385
# [1,2,3].blank? # => false
86+
#
87+
# @return [true, false]
7488
alias_method :blank?, :empty?
7589
end
7690

@@ -79,20 +93,28 @@ class Hash
7993
#
8094
# {}.blank? # => true
8195
# { key: 'value' }.blank? # => false
96+
#
97+
# @return [true, false]
8298
alias_method :blank?, :empty?
8399
end
84100

85101
class String
86-
BLANK_MATCHER = /\A[[:space:]]*\z/
102+
BLANK_RE = /\A[[:space:]]*\z/
87103

88104
# A string is blank if it's empty or contains whitespaces only:
89105
#
90-
# ''.blank? # => true
91-
# ' '.blank? # => true
92-
# ' '.blank? # => true
93-
# ' something here '.blank? # => false
106+
# ''.blank? # => true
107+
# ' '.blank? # => true
108+
# "\t\n\r".blank? # => true
109+
# ' blah '.blank? # => false
110+
#
111+
# Unicode whitespace is supported:
112+
#
113+
# "\u00a0".blank? # => true
114+
#
115+
# @return [true, false]
94116
def blank?
95-
self =~ BLANK_MATCHER
117+
BLANK_RE === self
96118
end
97119
end
98120

@@ -101,6 +123,8 @@ class Numeric #:nodoc:
101123
#
102124
# 1.blank? # => false
103125
# 0.blank? # => false
126+
#
127+
# @return [false]
104128
def blank?
105129
false
106130
end

activesupport/test/core_ext/blank_test.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,28 @@
55

66
class BlankTest < ActiveSupport::TestCase
77
class EmptyTrue
8-
def empty?() true; end
8+
def empty?
9+
0
10+
end
911
end
1012

1113
class EmptyFalse
12-
def empty?() false; end
14+
def empty?
15+
nil
16+
end
1317
end
1418

15-
BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", ' ', [], {} ]
19+
BLANK = [ EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", ' ', "\u00a0", [], {} ]
1620
NOT = [ EmptyFalse.new, Object.new, true, 0, 1, 'a', [nil], { nil => 0 } ]
1721

1822
def test_blank
19-
BLANK.each { |v| assert v.blank?, "#{v.inspect} should be blank" }
20-
NOT.each { |v| assert !v.blank?, "#{v.inspect} should not be blank" }
23+
BLANK.each { |v| assert_equal true, v.blank?, "#{v.inspect} should be blank" }
24+
NOT.each { |v| assert_equal false, v.blank?, "#{v.inspect} should not be blank" }
2125
end
2226

2327
def test_present
24-
BLANK.each { |v| assert !v.present?, "#{v.inspect} should not be present" }
25-
NOT.each { |v| assert v.present?, "#{v.inspect} should be present" }
28+
BLANK.each { |v| assert_equal false, v.present?, "#{v.inspect} should not be present" }
29+
NOT.each { |v| assert_equal true, v.present?, "#{v.inspect} should be present" }
2630
end
2731

2832
def test_presence

0 commit comments

Comments
 (0)