RubyBeans revisited (again) – Closures in Ruby

Tuesday, May 1st, 2007
Coffee Beans

A comment by Thomas Geis on my first RubyBeans post lead me to another rework of the RubyBeans metaprogramming example.

Thomas accurately points out:

I think the property should sit in a proxy-object, that does inform the listeners of its change. In your example, one could directly change the properties value from within the class without a call to the property_changed method.

This would be a concern for me. Isn’t it a concern for you?

Yes it is! I tried the proxy-object solution, but I am not satisfied with it for two reasons: the code get lengthy and inelegant, but mostly because the proxy-objects themselves aren’t protected from direct access.

I believe I have a nicer solution to protect the properties from direct access: closures. The first few lines of code remain unchanged:

class RubyBean

  def initialize
    @listeners = []
  end

  def register_listener(l)
    @listeners.push(l) unless @listeners.include?(l)
  end

  def unregister_listener(l)
    @listeners.delete(l)
  end

Now, observe how value is captured in the getter and setter blocks. The scope of the value local variable is the local block and the blocks passed in define_method. These blocks “close over” the value local variable.

  def self.property(*properties)
    properties.each do |p|
      value = nil
      define_method(p) { return value }
      define_method("#{p}=") do |new_value|
        return if value == new_value
        @listeners.each do |l|
          l.property_changed(p, value, new_value)
        end
        value = new_value
      end
    end
  end
end

Finally, here is an example of how RubyBeans would be used (were they not a Java idiom shamelessly ported for illustration purposes). The impotent_name= method cannot affect the name property, it will create a name instance variable, unrelated to the property.

class SimpleBean < RubyBean
  property :name, :firstname
  
  def impotent_name=(new_name)
    @name = new_name
  end
end

class LoggingPropertyChangeListener
  def property_changed(property, old_value, new_value)
    print property, " changed from ",
      old_value, " to ",
      new_value, "\n"
  end
end

test = SimpleBean.new
listener = LoggingPropertyChangeListener.new
test.register_listener(listener)
test.name = "Parker"
test.firstname = "Charlie"
test.firstname = "Maceo"
test.unregister_listener(listener)

Let me know if you spot something else!


Ozonesoft.net

Friday, March 16th, 2007

I am proud to announce the launch of my professional web-site: Ozonesoft.

RESTful Rails presentation

As a bonus, you can download the slides of the RESTful Rails presentation I gave at the Ruby Tuesday meetup this week, in Dublin. I hope you’ll enjoy reading it as much as I enjoyed writing it.


ZX81 nostalgia

Saturday, February 17th, 2007

Quasimondo has a beautiful set of macro photos of the ZX81’s keyboard. I was only a kid when my father brought one home. The ZX81 is the first computer I ever used and I have fond memories of it.

We used the 16K expansion kit which expanded our computational horizon to unthinkable length, like painting the screen black! The standard 1K would only let you paint about half the screen before running out of memory!

The keyboard was really unpractical so we used a mechanical keyboard laid out on top. This improved the ergonomy slightly. Slightly is the key.

My father also built a wooden cradle to protect the beast and dramatically improve its stability. Indeed, without it, even a light impact on the table would reset the machine.

These were the days…

technorati tags:


Five Tidbits You Didn’t Know About Me

Tuesday, February 6th, 2007

Not to drop the baton handed over by Jao, here are five things you might not know about me:

  1. I am the very proud father of two adorable monsters who have turned my life upside down, for the better! Sophie, the eldest, will turn three in a couple of days while Noah, the wee one, celebrated his first birthday a few weeks back. As the saying goes: we’ve got our hands full. I’m eternally grateful to my wife, Noreen, for giving them the greatest gift of all: life.
  2. I play the saxophone in a Blues & Rock band called Delta Creed. We play a couple of times a month in pubs around Dublin.
  3. I have worked for one year as a clarinet teacher in a music school, about fifteen years ago. Oh boy… poor kids.
  4. My father’s parents where Italian. My mother was born in Algeria. I am French. My kids are French and Irish. If everything goes according to plans, the next generation should invade Iceland!
  5. As a typical Frenchman, I love my food. My favorite is the Blanquette de Veau. If you’re curious, I suggest checking out LeChatMachine’s photoset on flickr describing how to cook a Blanquette de VeauBlanquette de Veau

One thing you surely know about me: I have been neglecting my blogging duties for far too long. Thanks you, Jao for giving me a jolt to start writing again.

Time to pass the baton to: Abhijit Nadgouda who has to be my most fervent reader, Coté from the inimitable Drunk & Retired podcast, Fintan Palmer a friend, Steve Dekorte father of Io, and Geoffrey Grosenbach from the Ruby on Rails podcast, the peepcode screencasts, etc. You know the drill: five facts, five more people and do not drop the baton!


Ruby Ireland first meet-up

Tuesday, October 24th, 2006

It took us some time to organize, but we finally had our first Ruby Ireland meet-up last night. The event took place in Mulligan’s on Poolbeg Street, a pub notorious for serving one of the best pint of Guinness in Dublin… an aspect we all appreciated!

Mulligan’s on Poolbeg Street
Picture by Dave Bushe AttributionNoncommercialNo Derivative Works All rights reserved.

Seven Rubyists turned up for this introductory meet-up. One half were professional users, the other half… envious! Unsurprisingly, Rails was the main topic of conversation, but we also touched on Ruby meta-programming, a personal favorite.

I really enjoyed this meet-up. I don’t know whether it was the night out — a rare occasion when you’re the proud father of two young monsters — or whether it was the friendly and passionate people who turned up, but one thing is sure: I’m looking forward to the next Ruby Ireland meet-up!

technorati tags:, , ,


Plugging Python decorators

Friday, October 20th, 2006

For the last few weeks, I have been having very interesting discussions with a work colleague on a wide set of topics ranging from computing to philosophy and family life. He is a smart, passionate and knowledgeable developer and an avid learner. I tried to convince him to start blogging and I am glad to see he has taken the plunge: ladies and gentlemen, give a warm welcome to Muharem Hrnjadovic!

PythonHis opening salvo is a three part mini-study of Python decorators: check out part one and part two on his blog. Before you ask, part three is in the making and will be available shortly.

technorati tags:,


Practical Common Lisp

Wednesday, October 18th, 2006

Practical Common LispLast Sunday, browsing the bookshops in town, “Practical Common Lisp” by Peter Siebel caught my eye. I remember reading it online about a year ago. It allowed me to rediscover Lisp, since, to my regret, I had to bid farewell to the programmable programming language when I left college. It might have been nostalgia but I thoroughly enjoyed this book. Thanks to Peter Siebel! I had no hesitation, I bought the hardcover straight away. I can only recommend it highly for anyone wanting to learn Lisp.

This post would not be complete without pointing you to Paul Graham’s “On Lisp”.


Reinventing the wheel and associated pains

Tuesday, October 17th, 2006

Have you ever visited Starke County, Indiana? I haven’t. I wouldn’t even have heard of it if it wasn’t for the little misadventure I’m about to relate. What lead me to Starke County is a rather bad habit that afflicts most of us, developers. No, not the lousy t-shirts… not the heavy coffee drinking… not the sleepless nights spent hacking… do we have that many bad habits? The one I want to single out today is our tendency to reinvent the wheel. I don’t really know why but we all believe we can do better than whatever framework, library or system currently exists. The pursuit of perfection is a laudable ambition but all too often, it is the way to pain, because, as this post will highlight, we underestimate the effort required to get a decent wheel.

Spinnin’ wheel

I’ll start by contradicting what I just wrote: reinventing the wheel is a good thing. Take web-frameworks. They come in all shapes, sizes and colors. The variety is so abundant there has to be one that fits your needs perfectly — finding it is the topic of another post. Why would you want to come up with your own implementation? As James Brown famously said please, please, please, please to which, far lesser known fact, he added not another flamin’ web-framework!. He was being polite. Yet, when Rails came out, it shook the web-framework arena with its simplicity and elegance. You might disagree with me regarding Rails’ qualities, but you cannot dispute the seismic impact it has had on web development and on the popularity of dynamic languages. If this does not convince you, take a look at Seaside, KPAX or Django. Obviously reinventing the wheel has some advantages, at the very least it fosters ideas and progress. Heck, Linux started as a reinvention of existing UNIX systems.

Wheel of misfortune

But there are contexts when reinventing the wheel is a very, very bad idea. The worst context I can think of is in a corporate environment when the wheel is not your core business. Why? Well, there are several reasons:

  1. you are going to spend time and resources building this new wheel,
  2. you are going to spend time and resources testing this new wheel,
  3. you are going to spend time and resources documenting this new wheel,
  4. you are going to spend time and resources maintaining this new wheel.

See a recurring pattern? To be fair, the first point is rarely underestimated. What tends to happen though is that the promised benefits seem to justify the building cost because the others are underestimated.

The testing cost is always neglected. Think about it: how can you ensure your code receives at least the same exhaustive testing as the one it is supposed to better. Consider the constant QA bashing endured worldwide and around the clock by Struts, Tapestry or Spring. Sure, you will still find the occasional bug. You will lose time and patience working around the issue, or even better, you will fix it and submit a patch. Will someone do this for your code?

The documentation cost… well… what documentation? Up-to-date documentation is the unicorn of software development: a beast of legends. Mind you, if you have a good unit-test coverage, it can serve as documentation and it is guaranteed to be in sync with the code. This still falls short of the documentation of the wheel you are replacing: books, articles or blogs. What’s your plan?

The maintenance cost is directly related to the previous two. The more tested your wheel is, the least it is likely to break down and require maintenance. If it does, the more documentation there is, the easiest it will be for a third party to resolve the issue. Let’s face it, chances are the people implementing your new wheel today will be gone tomorrow, there are so many wheels to reinvent elsewhere!

Back to Starke County

You are probably wondering what is the link with Starke County, so here is my little anecdote. It all started by a bug report sent by the sales team. They were demonstrating the product to some potential customers in New-York. Naturally, they had set the system’s time-zone to EDT/EST in accordance with the local time. The time on the command-line interface to the system was accurate but, somehow, the time on the web front-end was off by one hour. The issue was logged and we got cracking straight away.

To give you a bird’s eye view of the concerned parts of the system, the command line interface is implemented in C/C++, whereas the web front-end is Java based. It turned out the system uses its own home-made time-zone database for reasons I have yet to fathom. This database maps time-zones set by the administrator to UNIX or Java time-zones depending on the interface. We quickly spotted that EDT_EST was mapped to US/Indiana-Starke.

We ran simple tests on various platforms and where surprised to discover that the latest version of the JVM was giving the erroneous off-by-one answer. Hmm… weird. At that point we started to suspect something fishy. We even checked out Google earth to find out where the elusive Starke, unsuccessfully. Eventually, I stumbled upon this:

[…] other entries represent smaller regions like Starke County, Indiana, which switched from central to eastern time in 1991 and switched back in 2006.

It turned out the time-zone database on the Linux system was not up to date but the JVM one was. Java was right all along. Whoever populated the time-zone mapping database made a very poor choice when they picked US/Indiana-Starke as a representative of EDT_EST, especially when other candidates would be America/New_York, US/Eastern, EST5EDT… but what do I know.

Better still, the time-zone mapping table should have gotten the boot. There are wheels you should not even think about replacing. Without our home-made “improved” wheel, the choice of US/Indiana-Starke or America/New_York or anything else for that matter would have been left to the end-user, untouched by the system. Granted, the 25,000 potential users living in Starke County would still have suffered the bug, but the 20,000,000 potential users in New-York State would not have been affected — and I’m not even counting the other millions of people leaving on eastern time.

Where the wheel comes full circle

I hope you will remember this little anecdote next time you are thinking about reinventing the wheel. If you do, slow down and weight your options carefully. Is there an existing framework, library or system that already provides the functionality? To an acceptable degree? If not, is your employer fully aware of the risk and cost associated with your proposal? Make it clear! If you are self-employed, are you willing to take the risk and pay the cost? Are the benefits worth it? You get the picture: think it through. If you reach the conclusion that it is all worth it, you’re either mad or incredibly lucky, because you will get to fulfill your inner-geek deepest desire: inventing your very own wheel!

technorati tags:,


Writing code with style!

Wednesday, August 16th, 2006

If you want to improve your coding style, I have got a little gem of a book for you! I discovered it thanks to Stéphane Ducasse and his great collection of free Smalltalk books. It was written 10 years ago by Edward Kilmas, Suzanne Skublics and David A. Thomas (yes, Pragmatic Dave, from Pragmatic Programmer and Pickaxe fame) and it deals with writing Smalltalk with style.

It is aptly titled Smalltalk with Style.

The Smalltalk focus might not be of interest to you — although a bit of Smalltalk cannot hurt a serious programmer! — but the style guidelines are invaluable and can be easily adapted to other languages or incorporated into a coding standard.

technorati tags:, , ,


Build Io on Fedora Core 5

Thursday, July 27th, 2006

Following in my own footsteps — yes, it is a recursive process — here are the steps required to install Io on Fedora Core 5.

sudo yum install freeglut-devel pcre-devel libevent-devel

Once again, libsgml needs a special treatment:

> wget http://www.hick.org/code/skape/libsgml/libsgml-1.1.4.tar.gz
[...]
> tar xfz libsgml-1.1.4.tar.gz
> cd libsgml-1.1.4
> ./configure
[...]
> make

At this point, you will need to edit the Makefile. Replace:

install -m 644 -o root -g root --directory /usr/local/include/sgml

by:

install -o root -g root --directory /usr/local/include/sgml
install -m 644 -o root -g root include/Variant.h \
    /usr/local/include/sgml/Variant.h

Save your modifications and proceed with:

> sudo make install

Finally, to download, build and install Io:

> sudo yum install darcs
[...]
> darcs get http://www.iolanguage.com/darcs/Io
[...]
> cd Io
> make
[...]
> sudo make install

Enjoy Io!

technorati tags:, ,