October 17th, 2007
irb: Learning Ruby Quick
In my previous post I introduced the idea of using irb as a desktop calculator. If you are new to Ruby, however, using irb can have the side effect of teaching you Ruby. Everything you type in irb is a Ruby statement. The response you get from irb is the value Ruby returns from the evaluation of the statement you type. You can use this to try things out in Ruby to see how it behaves. Here is an example exploring how a Ruby Array handles some given Range objects as arguments to the “indexing” method []
:
irb(main):001:0> a = [1, 2, 3, 4, 5] => [1, 2, 3, 4, 5] irb(main):002:0> a[1..-1] => [2, 3, 4, 5] irb(main):003:0> a[1..a.size] => [2, 3, 4, 5] irb(main):004:0> a[1...-1] => [2, 3, 4]
Now we just saw first hand some of how we manipulate Arrays in Ruby. But what if we are curious about what else we can do with an Array? It would be really nice if we could quickly get a list of methods available for my Array. Oh, but we can! Every Ruby object has a methods
method that returns an Array populated with the names all the messages it responds to.
irb(main):005:0> a.methods => ["select", "[]=", "inspect", "compact", "<<", "&", "clone", "method", ... (over 100 other methods) ..., "unshift", "sort_by", "to_yaml_properties", "fill", "max", "is_a?", "uniq!", "[]"]
Oh, that is a lot of methods! My version of Ruby/irb returned 128 methods for the object, and they are hard to read all mixed up like that. Good thing we can sort them, too:
irb(main):006:0> a.methods.sort => ["&", "*", "+", "-", "<<", "<=>", "==", "===", ... (over 100 other methods) ..., "uniq", "uniq!", "unshift", "untaint", "values_at", "yaml_initialize", "zip", "|"]
By scanning the methods available to an object you can get an idea of what you can do with it before you even look at proper documentation (which you want to have handy, too). Using the methods
method from irb is also a fast way to recall the name of a method if you forget it and your text editor or IDE does not help you figure it out. I sometimes just try out methods unknown to me just to see what happens, and then I check the documentation shortly thereafter to ensure I understand it.
The most important aspect of irb that enabled me to learn Ruby and keep up with changes in the language was the ability to vet out short bits of code before putting them into a program. For example, if I need to ensure a complicated regular expression will match what I want it to, I can do the initial testing in irb. Then those tests done in irb that supply confidence that the regular expression is correct are copied into the unit tests. Here is a simple example to illustrate the idea:
irb(main):007:0> 'foo bar baz' =~ /\/ => nil
Oops! I expected an Integer result, which would denote there was a match. However, I forgot I was working in Ruby instead of an old version of grep, and the notations denoting a word boundary in regular expressions are different between the two. It is easily fixed:
irb(main):008:0> 'foo bar baz' =~ /\bbar\b/ => 4
One other trick I employ in irb is to get a list of currently loaded classes, at least as defined at the top level (i.e. a class within a class or module, like Net::HTTP
, will not show up, but Net
will and then one could drill down from there). This can be done because every class can be identified by a constant value, and a list of these constants can be obtained from the Object
class using the constants
class method:
irb(main):009:0> Object.constants.sort => ["ARGF", "ARGV", "ArgumentError", "Array", "BasicSocket", "Bignum", "Binding", "Buffering", ... (over 100 other entries) ..., "UNIXserver", "UNIXsocket", "URI", "UnboundMethod", "VERSION", "YAML", "ZeroDivisionError", "Zlib"]
Not all of the entries returned are classes (e.g. ARGF
and ARGV
), but it does not hurt to know about the other defined constants, too.
With irb at my disposal learning Ruby was a snap, and it was very fun. If you have not yet had the pleasure of learning Ruby then perhaps irb can make your journey more fun, too. Let me know if you try it out!