The Art of the Shortcut

April 4, 2004 10:00 AM

One thing you see a lot in Java programmers is the use of Javabean-style properties: classes with a pile of "get" and "set" methods that allow you to manipulate their state. Now the arguments as to whether this is acceptable practice or Considered Harmful are legion, and I'm not going into them today. Suffice to say I spend most of my time writing Java, and some habits get carried around with you.

One thing I wanted to do in Ruby, though, was to find some way to lessen the pain caused by having to change a bunch of properties at once. I did so by adding a method to the Object class that would allow me to pass in a hash of name->value pairs, and have them automatically mapped to object property "setter" methods. (In Ruby, the convention for a setter is to have a method called "foo=", which through a little operator-overloading magic allows you to write " = bar" in your code)

class Object
  def set_properties(props)
    props.each { |key, value| self.send("#{key}=", value) }

This makes the following fragments of code equivalent:

  1. = "Charles"""""
  2. user.set_properties ({ :name => "Charles", 
      :email => "", 
      :website => "" })

Of course, one of the most important things one should make sure of when writing a shorter way to do something, is that the short way isn't, say, 30% longer than the one you started with.

"Alright, we're here. Let us never speak of the shortcut again.".

1 TrackBacks

Listed below are links to blogs that reference this entry: The Art of the Shortcut.

TrackBack URL for this entry:

Charles Miller examines the getter/setter syndrome in Java1 from a usage (rather than the normal construction) perspective and devices a... Read More


Amen. It's easy to have a clever idea. The mark of a craftsman is to evaluate it in practice, and, most importantly throw it away if it turns out to be a bad idea.

I wrote an article on how Rails using this shortcut to relief controllers of per-attribute knowledge responsibility:

Oh, never mind that comment. Seems like trackback is working just fine for this :)

It seems to me that what you want is

user.with {
name = "Charles";
email = "";
website = ""

where 'with' simply aliases to instance_eval and you trust the client programmer not to abuse the fact.

Previously: Penny Arcade's Greater Internet Fuckwad Theory

Next: Cut With the Grain