What I love most about Ruby

June 29, 2010 § 1 Comment

I have some friends (Hi Dustin) that are serious language geeks, whom I often get into debates with. One of my common refrains is “to do it the Ruby way”, because (while Ruby has its warts) it does so many little things beautifully well. So, as future ammunition, I figured I should try to collect links to my favorite Ruby features (much as many others have already done before me).

I. Language Features

These are intrinsic features of Ruby the language that allow some really elegant API design and programming solutions.  Many syntactic elements are stolen from Perl, but generally employed with much better taste. 🙂

1. Implicit trailing block arguments (yield).

In Ruby, any method (function) can always take a block as an optional argument at the end. It doesn’t need to be declared, and it doesn’t even need to be inside the parentheses. It can be accessed implicitly by calling “yield”, or “reified” into an actual argument by declaring a “&block” argument. This is particularly nice for iterators, callbacks, and HTML templates. I used this heavily in my Dispatch library for MacRuby.

2. Literals

Ruby provides convenient, built-in literal syntax for all sorts of things. In addition, Ruby provides an alternate “%” notation (which can use any open/close character) to avoid the need for escaping the enclosing character.

  • blocks { block literal }
  • strings “foo” %q{foo}
  • symbols (unique strings) :foo %s’foo’
  • arrays [“foo”, “bar”] %w|foo bar|
  • dictionaries {:foo => “bar”} or {foo: bar}
  • ranges 0..5 1…3
  • regular expressions /reg.*/ %r(reg.*)
  • shell invocation `do this` %x!do this!
  • characters ?a
  • numbers (including binary, and allow “_” for readability) 0b1111_0000
  • Primitives: nil, true, false,

This dramatically reduces the syntactic noise when working with all kinds of constructs.

3. String interpolation

In addition, String, Symbol, Regexp, and Shell all support interpolation, where you can ‘inline’ a variable inside a string or other literal “these are #{count} reasons I love Ruby”

4. Array (de)composition, aka “Splat”

The Ruby splat operator (“*”) converts between arrays and discrete objects.  Thus, you can easily “explode”  an array into an argument list for a function, or assign a returned array to a list of variables.

5. Namespaces as objects

In Ruby, (nearly) everything is an object.  This includes Modules, which (among other things) serve as namespaces. Classes defined within a module are just constants within that namespace.  This  also means one can create convenience methods directly on that module, which reduces the need for global variables and can veil the complexity of the underlying classes.

6. “Compile-time” class methods

The Ruby Class class is actually a subclass of Module, and thus also a first-class objects.  What this means is that building classes is simply a matter of executing code within the context of a “class” scope.  As such — apart from the primitive “def” object for creating functions — all other directives (e.g., attribute properties, public/private) are really just class methods.

This means you can effectively extend or change the semantics of class construction just by extending the “Class” class. Ruby also makes it very clean and easy to define new class methods to use as factories, which avoids the “designated initializer” confusion of Objective-C.

II. Standard Library

The following functions aren’t part of the core language per se, but are baked into the standard library.

1. Transparent URL handling

There’s a Ruby module called “open-uri” that transparently extends the “open” method to work with URLs as well as files.  It makes network access brain-dead simple.

2. Smart Casting

As a strongly typed language, Ruby doesn’t automatically convert between different data types; but as a dynamic language, it doesn’t let you explicitly specify cast. So what does it do instead?

It defines a conventional set of “to_*” methods to handle conversions, many of which are implemented by Object and thus inherited by all other Ruby objects.  Cleverly, there are both “permissive” and “exact” versions, with the latter giving an error if no exact conversion is available.

  • to_a, to_ary, to_enum
  • to_f
  • to_hash
  • to_i, to_int
  • to_io
  • to_json
  • to_proc
  • to_s, to_str, to_sym
  • to_xml
  • to_yaml

The permissive versions are extremely short, which makes “casting” feel very lightweight, but unambiguous.

3. XML/HTML manipulation

Partly as a result of the above, Ruby provides some very elegant libraries for both generating and parsing XML and HTML. Importantly, the recent ones use CSS and/or XPath queries, which are much easier to use than explicit DOM or SAX parsing for common tasks.

§ One Response to What I love most about Ruby

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

What’s this?

You are currently reading What I love most about Ruby at iHack, therefore iBlog.

meta

%d bloggers like this: