Programming with Ruby (NFJS)

Posted on December 05, 2004 by Scott Leberknight

It's been a month since I went to the Reston No Fluff Just Stuff and I still haven't written all the sessions. Maybe next time I'll blog the sessions while I'm there. Anyway, went to a good session given by Dave Thomas on the Ruby programming language. It seems there has been a lot of discussion lately by Stu Halloway, Dave Thomas, and others about metaprogramming and how certain languages don't need the notion of patterns simply because the language supports the "patterns" as part of the language.

Some of the cooler things Ruby supports include closures, blocks, iterators, mixins, and the ability to add and remove methods dynamically from core classes like String. In Ruby, everything is an object, unlike Java and C# which have primitive and reference types. And Ruby does away with the special new keyword in favor of a special initialize method which is invoked when you call new to create an object:

myBook = Book.new("Programming Ruby")

Another cool thing is that Ruby provides native support for defining attributes and specifying whether they are readable and/or writeable using a shortcut notation:

attr_reader :title
attr_accessor :artist

The above defines a read-only attribute named title and a read/write attribute named artist. Even better you can directly access these attributes using dot notation, e.g. myBook.title and myBook.artist = "Dave Thomas" without needing to declare mundane Java-style getters and setters. The above are shorthand for a def block which is the formal notation for defining attributes. For example, the attr_accessor is equivalent to the following:

def artist
  @artist
end

def artist=(val)
  @artist = val
end

In Ruby, instance variables are always private and are prefixed with an @ symbol, e.g. @artist. That's kinda cool. No more project code convention arguments whether instance variables should be prefixed with an underscore, or always prefixed by the this keyword, or any other contrived mechanism for unambiguously identifying instance variables in code.

Ruby support for blocks and iterators is really cool. For example, since everything is an object, you can write code like the following:

3.times { puts "Hello, Ruby" }

myHash.each { |key, value|
  puts "#{key} -> # {value}"
}

IO.foreach("/my/file") do |line|
  process(line)
end

The first line in the examples above prints "Hello, Ruby" three times, as you would expect. Pretty nice. The next example shows iterating over a hash and printing the keys and values. The last example shows iterating over the lines in a file and calling some method process to handle each line. In Ruby a block is simply a "chunk" of code attached to a method. This has the nice side effect that you can pass around blocks of code to be executed in predefined methods. So you could define a method called do_twice and define it as such:

def do_twice
  yield
  yield
end

Then if you called the do_twice method using the line do_twice { puts "Ruby is cool!" }, the output would simply be "Ruby is cool!" printed twice.

There was a lot more to Dave's presentation including examples of scraping a web page, connection to a database, and information on Ruby web and persistence frameworks. All in all, Ruby seems like a pretty cool language, and I'd like to try it out on a few projects. Oh wait, I just remembered that requires having some free time...

Check out Dave's Programming Ruby book.



Post a Comment:
Comments are closed for this entry.