For the past eight months I've been evangelizing Ruby and Rails to my co-workers, colleagues, family, and friends. Having sent the same email out a few times now, I thought it might be easier just to preserve my banter publicly.

Here's a basic method to retrieve the "id" field for the most recent row from a database table:

  def get_newest_id
    find(:first, :order => 'date DESC').id

find() is one of Rails' ORM methods. As you can see, the parameters use an appreciably straightforward nomenclature and syntax. Everything is an object in Ruby, and so to access the "id" field of the database row returned by find() we simply append ".id" to the method send. Since this is the last line of the method in question, the result of this evaluation is the return value of the method. This is a basic example, but gives you an idea of how larger operations might be streamlined, both logically and aesthetically.

Ruby provides a facility called "Mixins," that allows for the use of custom methods as though they were built in to the language's standard libraries (among other things). For the purposes of this example let's take a quick look at some Ruby code that uses built in Ruby methods:

    # Define a string variable.
    variable = "Hello MONKEY"

    # This will output "string".
    print variable.class.to_s.downcase

The above example: 1) determines the data type of 'variable' using the Ruby method class(), returning a class object, 2) converts the class object into a string using the Ruby method to_s(), returning a string object with the value "String," 3) converts all characters of the string object to lower case, and 4) outputs the result "string."

Now that we've seen how to apply methods in rapid yet elegant succession, let's move on to a Mixin method I wrote. My method is called gsubs(), and it applies a series of regular expression substitutions on a string, using the Ruby built in method gsub(). Here is the code that calls gsubs():

    # Define a series of substitutions that we want to
    # perform on our string value, and then execute  
    # these substitutions via gsubs(). The variable  
    # subs[] is an array of arrays,where the first  
    # element of each sub-array is the pattern to 
    # search for and the second element is the 
    # replacement value.
    substitutions =  []
    substitutions << ['cool', 'awesome']
    substitutions << ['good', 'amazing']

    # This will output "Rails is amazing and awesome".
    print "Rails is good and cool".gsubs(substitutions)

Here is my gsubs() method, performing multiple gsub() operations on a string.

    def gsubs (subs)
      value = self

      subs.each {
        |sub| value = value.to_s.gsub(/#{sub[0]}/, sub[1])


"self" represents the variable that is calling this method, so in this case "self" represents the string value "Rails is good and cool." "substitutions.each" is the iterator control block, "|sub|" defines the iterator variable, and "gsub(/#{ sub[0] }/, sub[1])" calls gsub() with the first argument "/#{ sub[0] }/", and the second argument "sub[1]". The first argument to gsub is the pattern to search for, and the second argument is the replacement to use. The code "#{}" is used to reference a variable value, hence "/#{ sub[0] }/" is placing the value of "sub[0]" in between the two "/.../" characters, which are used by gsub() to define the search pattern. As you can see there is an incredible amount of work being done on that single line, but the code remains concise and highly readable, even to a newcomer.

NB: Let it be noted that the examples above do not do justice to the power or flexibility of Ruby or Rail's. The commentary on this page is limited to simple examples so as to promote immediate appreciation for Rails, and thus avoid unnecessary turn-offs and confusion.

[ commentary :: engineering ]

Last updated December 14, 2010