I’ve been writing a web application in Ruby recently, in order to glue together a couple of fairly complicated systems into something approaching a sane workflow.

You might think I’d use Rails. Once upon a time I thought I’d write applications in Rails too. I bought the book, wrote some toy apps, and set it aside until I next needed it.

In the meantime, Rails got bigger and bigger. It adopted controversial trendy libraries. Its limitations started to become apparent, and even the hipsters started abandoning it. When I looked at Rails 3, I decided it was no longer heading in a direction I wanted to go.

I’m not a big fan of frameworks anyway. “Why I Hate Frameworks” discusses part of the reason—they tend to result in too much abstraction. They also tend to result in lots of indirect external dependencies; your platform choices, for example, can end up being made for you. And then there’s the opinionated way they tend to dictate your other choices. To me, a framework is a library with delusions of grandeur; it’s like hiring a plumber because you need the sink fixed, and having him lecture you about how you should landscape your front yard.

That’s not to say that there isn’t a place for frameworks. Sometimes you are doing something that’s very complicated but standardized, like building a GUI application. Sometimes you’re a beginner, and you want someone to tell you what to do and how to do it. But mostly, frameworks annoy me.

There are a few exceptions, though. One is the framework I’ve been using for my trivial web application. It’s called Sinatra, and is not much more than a thin layer of syntactic sugar sprinkled on top of HTTP.

I don’t need widgets or a sophisticated templating system, as the look and feel has been supplied to me by the corporate web design team. I don’t even need a database, because my application just needs to pull data from one system and push/pull it with another, via REST APIs. The Ruby rest-client Gem makes that easy; it basically does for REST calls what Sinatra does for HTTP servers. So Sinatra gets the job done. Rails is a faster way to get CRUD apps started, but if you have a problem that isn’t CRUD, I’d suggest checking out Sinatra.

Ruby tends to lend itself to these kinds of domain-specific languages. For instance, here’s a function which implements locking using a temporary lock file and the POSIX flock call, to ensure exclusive access between multiple processes:

LOCK_FILE='/tmp/lockfile.tmp'

def exclusively
  File.open(LOCK_FILE, File::CREAT|File::RDWR, 0644) do |file|
    file.flock(File::LOCK_EX)
    yield
    file.flock(File::LOCK_UN)
  end
end

You can then put a lock around some access to a resource like this:

puts "Entering exclusivity zone..."
exclusively do
  puts "I'm in!"
  sleep 20 # simulate access to slow resource
  puts "Exiting exclusivity zone..."
end

For more elaborate lock file requirements, there’s the lockfile gem.