Saturday, September 18, 2010

Poro 0.1.0 Released

Today I released the Ruby Gem Poro v0.1.0. It is a first working version of an extensible persistence engine. Currently it only has support for MongoDB, but I plan on also supporting SQL and MemCache before going to version 1.0.

You can get it by either calling gem install poro or by downloading or forking the source on GitHub.

Poro takes a slightly different philosophy from existing gems: Recently I was struck with a thought, in the Ruby world the majority of persistence engines take philosophy of having a base persistence object, and then subclassing that object for everything that needs persistence. This, it seems to me, puts the thought of persistence before the thought of what the object does. In other words, it seems like the chicken before the egg.

In my mind, one should first be worried about what an object does and implementing that. After that, they should be able to transparently add persistence to the object, without actively affecting it.

Poro (which stands for Plain Ol' Ruby Object) tries to take a hands-off approach. It does this by generating and configuring persistence management objects--called contexts--that manage the persistence for a given class. Thus, each class that one wishes to persist has a context sitting off to the side, that can be used (in a functional language like way) to persist an object.

Of course, I realize the convenience of models, so there is a basic model mixin that can be used to your object to add methods like find and save. (In the future, I plan on breaking apart this mixin into several modules that can be included all at once in the same way--as they are now--or in pieces, so that you can add only the pieces you want to use.

At this point, the major thing missing from Poro is testing and tuning. It will probably contain bugs and be slow, but I have plans to use the MongoDB context for a project soon, so it'll should be brought up-to-snuff relatively quickly.

Thursday, January 7, 2010

Rant: Names Are NOT Identifiers

Names Everywhere

I see this happen often: Someone creates a list of items with a "name" column. The backend team uses the name to fetch and compare these items. The UI team uses the name as a human readable description. Hilarity ensues.

Let me back-up and give an example: Let's say we have a list of states that an order can be in, things like "New", "Being Fullfilled", "Shipped", etc. The backend team, naturally, writes code like "Transition all the orders that are in the state 'New' and over 2 days into the state 'Overdue'". The front-end team creates a list of Orders that clients can view online and places the state name on the screen.

So what happens when it is decided that "New" needs to read "Pending"? If the UI team changes the name in the table to "Pending", all the code written around lookup and comparison to "New" breaks!

Names are Two Concepts in One: Identifiers and Labels

What happened here is that the developers confused the concept of an identifier with a label. The former should never be shown in a UI, but should always be used by developers for look-up, comparison, and whatever else they need. The latter should only ever be used for user display, and never for anything else.

In other words, mixing these into a single column is a layering violation, because you are mixing business logic and user interface display layers together! Making sure you don't breech these layers ensures that you can change the label all willy-nilly at anytime and not break anything.

What About My "id" Column?

As a last note, I often get asked (which pertains mostly to users of ORMs that rely on a numeric id column as a convention) is: why not use the numeric id as an identifier? In a small project this is probably fine. But in large or long running projects, it can get more complex: Sometimes the table's contents aren't predicable enough. FOr example, sometimes you have multiple clients running the same application, but with different (developer defined) entries in their own databases. The numeric IDs just aren't reliable because they are created via a sequence counter (auto-increment, serial, whatever). You are just asking for trouble if your project becomes anything more than a pet one.