Understanding nil?, empty? and blank? in Ruby and Rails

When first learning Ruby and Rails, I often used the methods nil?, empty? and blank? incorrectly. This lead to frustration when attempting to implement them in conditional logic structures. My background in PHP and Actionscript only worsened matters. These languages utilize similar constructs, however, in some cases they return the opposite value of their Ruby counterparts. 

I thought a post with a few IRB snippets would aid in my understanding of these methods. Let's begin with nil?. nil? is a method that can be called on any Ruby object to check if it exists and that it is valid. This method is useful when setting up conditional branches or when ensuring an object exists before calling its members. 

In Ruby, all classes inherit from the Object class. nil? is a method of Object; therefore, unless explicitly overridden, all classes have access to nil?. To better understand how Ruby expresses the concept of a non existent object, we need to look at its pseudo-variable nil. The same idea in other languages is often mapped to the primitive type, null or NULL. Depending on the language, NULL may point to nothing at all. Ruby differs here, in that, nil references an actual class called NilClass which exposes methods. This is why it's possible to do seemingly illogical things like:

nil.nil?
=> true


When calling on an object that is non existent, invalid or explicitly set to nil, an instance of the singleton NilClass is returned. A few examples will illustrate how this works.

cool_people = {:conan_the_destroyer => "man", :red_sonja => "woman"}

cool_people[:george_bush_II]
=> nil
cool_people[:george_bush_II].class
=> NilClass
cool_people[:george_bush_II].nil?
=> true
cool_people[:conan_the_destroyer].nil?
=> false

test_var = nil
test_var.nil?
=> true

[].nil?
=> false

"".nil?
=> false

0.nil?
=> false

false.nil?
=> false


Next, we have the empty? method. Unlike nil?, empty? is only available on some Ruby objects. String, Hash and Array are a few of the classes that implement it. When calling empty? the receiving object is being checked to see if it possesses a non-nil value or values. empty? (at least for the mentioned classes) returns either true or false. 

["Larry", "Curly", "Moe"].empty?
=> false

[""].empty?
=> false

[].empty?
=> true

{}.empty?
=> true

"".empty?
=> true

0.empty?
=> NoMethodError: undefined method `empty?' for 0:Fixnum

test_var2 = nil
test_var2.empty?
= > NoMethodError: undefined method `empty?' for nil:NilClass


The last example above clearly illustrates why one would get unexpected results when trying to do things like this:

dog = {:name => "Beauregard"}
puts "What kind?" if dog[:breed].empty?
=> NoMethodError: undefined method `empty?' for nil:NilClass

# Use nil? instead.
puts "What kind?" if dog[:breed].nil?
=> What kind?


This leads right into Rails' blank? method. The method blank? is Rails centric, in that, it does not exist in Ruby. It basically queries an object's state using both nil? and empty? in one call. Here's a line straight from Rails' API documentation. 

“An object is blank if it‘s false, empty, or a whitespace string.  
For example, "", " ", nil, [], and {} are blank.”

For instance, I often use blank? when operating on form field values that are considered optional by a model. Going back to the dog hash, we can see how blank? simplifies testing for values.

script/console >>

dog = {:name => "Beauregard"}
puts "What kind?" if dog[:breed].blank?
=> What kind?

dog = {:name => "Beauregard", :breed => ""}
puts "What kind?" if dog[:breed].blank?
=> What kind?

Let me know if I missed anything.


原文: http://www.simplecircle.net/blog/understanding-nil-empty-and-blank-in-ruby-and-rails

你可能感兴趣的:(Understanding nil?, empty? and blank? in Ruby and Rails)