Monday, September 13, 2010

Callbacks

I generally tend to find callbacks confusing when called callbacks in an Object Oriented context because they drop the level of abstraction too low. That tends to force developers to think about the low-level mechanism of calling back instead of the Object Oriented concept the callback is trying to achieve, so they end up with no abstract concept at which they could stop tracing through the code and take it for what its name says.

For example, if the API says that the sort method takes a "callback" block of code in Ruby, that does not say anything about what that callback does, and makes it hard for the developer to guess what parameters it receives without reading the implementation code. On the other hand, if the API says the sort method takes a "comparator" block, it gives the developer much more knowledge on what the block's responsibility is and what parameters to expect without having to read through the code.

So, what are some examples of callbacks? Comparators, renderers, converters, translators, etc...

The reason I bring this up is I often run into APIs in Ruby/Rails business projects that simply take a block without naming it, making it difficult to guess what the block does without digging through the implementation.

For example, an API with print(data, &block) or just print(data) does not tell me much about the passable block in the first case or if I could even pass a block in the second case (although the API accepts it). I would have to read through the implementation to find out. However, if the API was print(data, &renderer), I would much more likely guess then that I can pass a renderer that receives the printable data for custom rendering before the actual printing occurs.

So, give your callbacks better names, and you will help developers parse through and understand your APIs faster.

3 comments:

Frederick said...

A block with a name and some sort of context about what it's used for? You mean an interface? ;)

Ryan Briones said...

here was my first thought. fun experiment. could potentially be better with a declarative API

http://gist.github.com/581476

Mario said...

This gave me a, "Well, duh!" moment. Thanks for that. I have been in the habit of just using &block. No more.