| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Object | 
					
						
							|  |  |  |   # An object is blank if it's false, empty, or a whitespace string. | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # For example, `nil`, `''`, `'   '`, `[]`, `{}` and `false` are all blank. | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ### Example | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # !address || address.empty? | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # can be simplified to | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # ```ruby | 
					
						
							|  |  |  |   # address.blank? | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   def blank? | 
					
						
							|  |  |  |     respond_to?(:empty?) ? !!T.unsafe(self).empty? : false | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   # An object is present if it's not blank. | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = !blank? | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # Returns the receiver if it's present, otherwise returns `nil`. | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # `object.presence` is equivalent to `object.present? ? object : nil`. | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ### Example | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # state   = params[:state]   if params[:state].present? | 
					
						
							|  |  |  |   # country = params[:country] if params[:country].present? | 
					
						
							|  |  |  |   # region  = state || country || 'US' | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # can be simplified to | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # region = params[:state].presence || params[:country].presence || 'US' | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T.nilable(T.self_type)) } | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   def presence | 
					
						
							|  |  |  |     self if present? | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NilClass | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # `nil` is blank: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # nil.blank? # => true | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(TrueClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def blank? = true | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(FalseClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = false # :nodoc: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FalseClass | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # `false` is blank: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # false.blank? # => true | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(TrueClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def blank? = true | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(FalseClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = false # :nodoc: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TrueClass | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # `true` is not blank: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # true.blank? # => false | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(FalseClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def blank? = false | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(TrueClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = true # :nodoc: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Array | 
					
						
							|  |  |  |   # An array is blank if it's empty: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # [].blank?      # => true | 
					
						
							|  |  |  |   # [1,2,3].blank? # => false | 
					
						
							|  |  |  |   # ``` | 
					
						
							|  |  |  |   sig { returns(T::Boolean) } | 
					
						
							|  |  |  |   def blank? = empty? | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = !empty? # :nodoc: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Hash | 
					
						
							|  |  |  |   # A hash is blank if it's empty: | 
					
						
							|  |  |  |   # | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # {}.blank?                # => true | 
					
						
							|  |  |  |   # { key: 'value' }.blank?  # => false | 
					
						
							|  |  |  |   # ``` | 
					
						
							|  |  |  |   sig { returns(T::Boolean) } | 
					
						
							|  |  |  |   def blank? = empty? | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = !empty? # :nodoc: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Symbol | 
					
						
							|  |  |  |   # A Symbol is blank if it's empty: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # :''.blank?     # => true | 
					
						
							|  |  |  |   # :symbol.blank? # => false | 
					
						
							|  |  |  |   # ``` | 
					
						
							|  |  |  |   sig { returns(T::Boolean) } | 
					
						
							|  |  |  |   def blank? = empty? | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = !empty? # :nodoc: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class String | 
					
						
							| 
									
										
										
										
											2024-01-18 22:18:42 +00:00
										 |  |  |   BLANK_RE = /\A[[:space:]]*\z/ | 
					
						
							| 
									
										
										
										
											2023-12-16 11:47:46 +00:00
										 |  |  |   # This is a cache that is intentionally mutable | 
					
						
							|  |  |  |   # rubocop:disable Style/MutableConstant | 
					
						
							| 
									
										
										
										
											2023-11-26 15:36:02 -08:00
										 |  |  |   ENCODED_BLANKS_ = T.let(Hash.new do |h, enc| | 
					
						
							|  |  |  |     h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING) | 
					
						
							|  |  |  |   end, T::Hash[Encoding, Regexp]) | 
					
						
							| 
									
										
										
										
											2023-12-16 11:47:46 +00:00
										 |  |  |   # rubocop:enable Style/MutableConstant | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   # A string is blank if it's empty or contains whitespaces only: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # ''.blank?       # => true | 
					
						
							|  |  |  |   # '   '.blank?    # => true | 
					
						
							|  |  |  |   # "\t\n\r".blank? # => true | 
					
						
							|  |  |  |   # ' blah '.blank? # => false | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   # | 
					
						
							|  |  |  |   # Unicode whitespace is supported: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # "\u00a0".blank? # => true | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |   def blank? | 
					
						
							|  |  |  |     # The regexp that matches blank strings is expensive. For the case of empty | 
					
						
							|  |  |  |     # strings we can speed up this method (~3.5x) with an empty? call. The | 
					
						
							|  |  |  |     # penalty for the rest of strings is marginal. | 
					
						
							|  |  |  |     empty? || | 
					
						
							|  |  |  |       begin | 
					
						
							|  |  |  |         BLANK_RE.match?(self) | 
					
						
							|  |  |  |       rescue Encoding::CompatibilityError | 
					
						
							| 
									
										
										
										
											2023-11-26 15:36:02 -08:00
										 |  |  |         T.must(ENCODED_BLANKS_[encoding]).match?(self) | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  |       end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(T::Boolean) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = !blank? # :nodoc: | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Numeric # :nodoc: | 
					
						
							|  |  |  |   # No number is blank: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # 1.blank? # => false | 
					
						
							|  |  |  |   # 0.blank? # => false | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(FalseClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def blank? = false | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(TrueClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = true | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Time # :nodoc: | 
					
						
							|  |  |  |   # No Time is blank: | 
					
						
							|  |  |  |   # | 
					
						
							| 
									
										
										
										
											2024-04-26 20:55:51 +02:00
										 |  |  |   # ```ruby | 
					
						
							|  |  |  |   # Time.now.blank? # => false | 
					
						
							|  |  |  |   # ``` | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(FalseClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def blank? = false | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-26 10:05:14 -08:00
										 |  |  |   sig { returns(TrueClass) } | 
					
						
							| 
									
										
										
										
											2024-01-20 10:13:18 -08:00
										 |  |  |   def present? = true | 
					
						
							| 
									
										
										
										
											2023-11-26 09:33:42 -08:00
										 |  |  | end |