nil?, empty?, blank? trong Ruby on Rails - sự khác biệt thực sự là gì
Cung cấp bởi Ruby Có thể sử dụng trên bất kỳ đối tượng nào Sẽ chỉ trả về true khi thực sự là nil. Ví dụ: nil . nil ? # => true false . nil ? # => false 0. nil ? # => false "" . nil ? # => false Đây cũng là phương thức được cung cấp bởi Ruby ...
- Cung cấp bởi Ruby
- Có thể sử dụng trên bất kỳ đối tượng nào
- Sẽ chỉ trả về true khi thực sự là nil. Ví dụ:
nil.nil? # => true false.nil? # => false 0.nil? # => false "".nil? # => false
- Đây cũng là phương thức được cung cấp bởi Ruby
- Khác với nil?, empty? chỉ sử dụng trên các đối tượng dạng tập hợp(collection) như Hash, Array, Set
- Phương thức sẽ trả về true khi tập hợp không có phần tử nào Ví dụ:
[].empty? # => true {}.empty? # => true Set.new.empty? # => true
- Tuy nhiên, phương thức này lại không bao gồm trong Enumerable, nguyên nhân là bởi không phải kiểu Enumerable nào khi lặp cũng trả về giá trị. Để biết thêm thông tin có thể tham khảo tại đây Ví dụ:
fib = Enumerator.new do |y| a = b = 1 loop do y << a a, b = b, a + b end end fib.empty? # NoMethodError: undefined method `empty?' for #<Enumerator:
- Bạn cũng có thể sử dụng empty với String (bởi vì String là mảng các ký tự). Ví dụ:
"".empty? # => true " ".empty? # => false
- Vấn đề khi sử dụng empty? là bạn phải biết chắc chắn rằng kiểu của đối tượng bạn đang sử dụng là Array hay nil. Nếu không biết trước điều này thì sử dụng nó sẽ không an toàn. Khi đó, bạn sẽ cần check điều kiện nil? trước. Ví dụ:
object = rand > 0.5 ? nil : array object.empty? # can raise an exception if !object.nil? && !object.empty? # doh... # do something end
Đó chính là lý do mà Rails định nghĩa phương thức blank? trong ActiveSupport.
- Cung cấp bởi Rails
- nil và false rõ ràng là blank còn true thì không.
class NilClass def blank? true end end class FalseClass def blank? true end end class TrueClass # true.blank? # => false def blank? false end end
- Đối với Array và Hash thì là blank? khi chúng empty. Điều này được thực hiện bằng cách sử dụng alias_method như bên dưới:
class Array # [].blank? # => true # [1,2,3].blank? # => false alias_method :blank?, :empty? end class Hash # {}.blank? # => true # { key: 'value' }.blank? # => false alias_method :blank?, :empty? end
- Khác với String#empty? chỉ kiểm tra trên độ dài của chuỗi thì String#blank? còn kiểm tra thêm cả khoảng trắng. Ví dụ:
class String BLANK_RE = /A[[:space:]]*z/ # A string is blank if it's empty or contains whitespaces only: # # '.blank? # => true # ' '.blank? # => true # " ".blank? # => true # ' blah '.blank? # => false # # Unicode whitespace is supported: # # "u00a0".blank? # => true # 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? || BLANK_RE.match?(self) end end
Điều này thuận tiện cho các ứng dụng web vì bạn thường muốn từ chối hoặc xử lý các chuỗi khác nhau chỉ chứa các khoảng trắng. - Logic cho các class khác là nếu nó có cài đặt empty? thì có thể sử dụng được blank?. Điều này thật thú vị. Hãy nhìn cách cài đặt blank? cho Object ở dưới:
class Object # An object is blank if it's false, empty, or a whitespace string. # For example, +false+, ', ' ', +nil+, [], and {} are all blank. # # This simplifies # # !address || address.empty? # # to # # address.blank? # # @return [true, false] def blank? respond_to?(:empty?) ? !!empty? : !self end
Trong đó, !!empty? chỉ sự phủ định nhân đôi, điều này rất hữu ích trong trường hợp giá trị là nil, một chuỗi số hay các giá trị trả về là true, false khác. Bằng cách này giá trị trả về luôn được chuyển sang kiểu boolean:
!!true # => true !!false # => false !!nil => false !!0 # => true !!"abc" # => true
- Number và Time sẽ không có blank?. Chúng sẽ luôn trả về false.
class Numeric #:nodoc: # 1.blank? # => false # 0.blank? # => false def blank? false end end class Time #:nodoc: # Time.now.blank? # => false def blank? false end end
- Được cung cấp bởi Rails
- present? là phủ định của blank? và có thể sử dụng ở bất cứ đâu
class Object # An object is present if it's not blank. def present? !blank? end end
- Cung cấp bởi Rails. Đôi khi bạn muốn viết một logic như:
params[:state] || params[:country] || 'US'
Nhưng bởi vì các tham số được nhập từ form nên đôi khi chúng có thể rỗng("") và khi đó chúng sẽ trả về ' ' thay vì 'US' như mong muốn. Lúc này thì presence rất hữu ích. Thay vì phải viết
state = params[:state] if params[:state].present? country = params[:country] if params[:country].present? region = state || country || 'US'
thì bạn có thể viết là
params[:state].presence || params[:country].presence || 'US'
- Phương thức này được cài đặt rất đơn giản:
class Object def presence self if present? end end
Nếu bạn làm việc với Rails, tôi khuyên bạn nên sử dụng prensent? hoặc blank? hoặc cả hai. Chúng có thể làm việc trên tất cả các đối tượng, làm việc trực quan tốt hơn và bạn không phải kiểm tra nil ở bất kỳ đâu.
Bài viết gốc: https://blog.arkency.com/2017/07/nil-empty-blank-ruby-rails-difference/