This post originated from an RSS feed registered with Ruby Buzz
by Eric Stewart.
Original Post: Ruby, hashes, and method signatures
Feed Title: Ponderings On Ruby
Feed URL: http://blog.eric-stewart.com/category/programming-ruby.rss
Feed Description: This is the Ruby related section of Eric Stewart's weblog. These entries will be the commentary of a long time Java/C++ programmer that started exploring Ruby in 2003.
I was chatting with a friend the other day who recently started to explore Ruby and Rails. One of the things that had struck him, being from a C++ and Java background, was the “strange” use of hashes (and symbols) in method signatures within Rails. So, for example:
link_to"Back",{:controller=>'pages',:action=>'show',:id=>@last_page_visited}link_to"Delete this page",{:action=>"destroy",:id=>@page.id},:confirm=>"Are you sure?"link_to"Help",{:action=>"help"},:popup=>truelink_to"Busy loop",{:action=>"busy"},:popup=>['new_window','height=300,width=600']link_to"Destroy account",{:action=>"destroy"},:confirm=>"Are you sure?",:post=>true
As I understand his comments, it’s awkward and not intuitive for people coming from other languages and platforms to see this mixture of explicit values and hash values in the parameter list to the method. I’m sure many people have come to Rails and/or Ruby with the same confusion and just adopted by example without looking under the hood. Let’s look at the method definition and examine it further.
The first argument, name, doesn’t seem to bother people too much as it is a required, explicit parameter. But what is going on with options? First of all, notice that options is an argument with a default value of {}, an empty hash. In our examples above we are passing explicit hashes, which makes sense as well since our second argument expects to be (and defaults to) a hash.
But I could have written some of these calls a different way. Instead of
In this case the only arguments I am passing in are options that belong to the first hash argument. Since I want the remaining arguments past the options to default, I can just use hash syntax and omit the braces and Ruby happily rolls them into a single has argument for me.
Named Arguments
What is going on here is a Rubyish way to provide named (or keyword) arguments. They can be expecially confusing when mixed with other arguments but really help when you have a variable number of arguments that you might support in different combinations and don’t want to require a long, exaustive list of optional arguments with a lot of nil default values. It also makes it very useful when passing on arguments from one call to another.
Argument Grouping
Looking back at our link_to examples, there are many cases where there are two hashes. The options hash are those named arguments that are used by link_to in creating the href for the link. The html_options are a completely different group that are used to definte the html attributes for the link we are trying to generate.
Convenience
It’s really all for convenience. As Rails has progressed we have seen many methods progress from a multitude of separate methods that are convenience methods for making a call to another that have rolled up into a single method with named parameters.
A good example of this is ActionController::base.render, which used to have an assortment of related calls such as: