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

Posted by Elliott Golden
header line
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.
Comments

Facebook Fan Pages and Static FBML Basics

Posted by Elliott Golden
header line
I was recently hired to set up a Facebook Fan Page a.k.a Page and a custom branded tab for UEFA Champions League Soccer and Heineken. Although the core technology required to make this happen is dead simple, learning my way through some of Facebook's quirks and limitations proved to be the real challenge.

For starters, it wasn't immediately obvious that a Page must be associated with a personal account. This key bit of information was never clearly presented to me as I "logically" navigated Facebook in an attempt to create the new Page. If a Page is being created for a client, it's important to decide who the personal profile will represent, as a person's full name will be required. For my client, I initially set up the personal account under my own name. The client then hired a moderator to regularly post content and manage the Page. Even though he had been added to the Page as a proper moderator, his posts were still being credited to the name associated with the personal account—mine. I was able to fix this by changing the username of the personal account to that of the moderator.

The project required a custom tab that would be nothing more than some HTML with a few external links, some absolutely positioned CSS rollovers and a couple of name anchors.

Facebook provides a simple app that enables this—Static FBML. Once the app has been installed for your Page, you can paste your HTML (including your external stylesheet call) into the app's textarea. Again, simple stuff, but here's something to note.  Since the <html>, <head> and <body> elements are already part of the parent Facebook page be sure to omit these (both opening and closing) in the markup you enter into Static FBML. 

When developing the markup and CSS, I prefer to work on local instances of the code. As I reach certain points, I copy and paste the code into Static FBML to see how it renders in the production environment. Updating the HTML provided instant results as expected, updating the CSS was a different story though. Facebook caches external stylesheets with a vengeance. I found two ways to get around this. You can use ugly inline CSS if your requirements are minimal. This makes it a pain to edit and also does not provide support for pseudo classes. i.e., Forget about using :hover and the like. The smart solution is to append an arbitrary query string to the end of the external stylesheet's URL. This acts as a cache buster.

<link href="http://www.my_server.com/my_stylesheet.css?version=1" rel="stylesheet" type="text/css" />


To force Facebook to use the newly edited stylesheet, just increment the number on the query string each time an edit is deployed.

Beyond the items already mentioned, I found that at times my local dev code would render as expected in the main browsers for both Mac and PC, but when deployed to Facebook the layout would not render in the same way. I found simpler CSS layout techniques to be the least problematic. As for Javascript I didn't use any in this project. However, from what I have read, standard JS is barely supported or not supported at all for Static FBML apps.
Comments
Posts 1-2 of 3


top All content in this site is copyright protected by either Simple Circle llc or its respective clients.   © 1999-2010
Validate XHTML