Morning standup went as expected, Rob and I were back to work again on the story we'd began the week with. The module we had extracted for allocating addresses was more or less done. We spent a few minutes discussing our strategy for integrating back into the model that would use it. All of the 'old' behavior was still in place through various lifecycle hooks. There were two before_save hooks and one validation hook we'd need to change. Given there was a lot of code already that depended on this existing behavior Rob and I were hesitant to just start ripping it out. It made more sense to write the new code in parallel with the old keeping everything working until the last possible moment. This way we could have some certainty that our new code in the model worked before we were forced to consolidate our changes with the rest of the system.
Over another great Relevance provided lunch it was decided that I would be switching projects in the afternoon. I felt bad about leaving Rob midstream, but consoled myself with the fact that I probably wasn't very much help anyway. He picked up Jason as a pair for the afternoon and I went with Chad.
Chad and I spent a couple hours spiking out client side certificate validation in JRuby and Jetty. We generated a little Rails project then pulled down warbler and jetty-rails. Getting Rails up and running on Jetty with jetty-rails was mindlessly easy. We hit our first bump trying to get an SSL listener up and running in Jetty. We spent a few minutes reviewing the jetty-rails documentation and found no mention of how we could achieve this. In the end we just copied the jetty-rails launcher script and modified it to suit our purposes. This was just a spike after all. We launched our new script and surprisingly the thing worked! Chad and I reported our success back to Stuart and Larry, then moved on. We knew we could make JRuby work, if we needed to.
Chad and I had a few free moments and I decided to take him up on his offer of a 10 minute tour of RSpec2. He's quite enthusiastic about the new metadata model and spent most of our time telling me about that. My very basic understanding is that everything you declare about a specification is captured in metadata which is accessible from pretty much anywhere you'd care to get to it. This makes RSpec2 extensions a breeze to write. Oh, and its really fast too, he'd want you to know that.
With my RSpec2 introduction complete I moved on to pair with Larry on a Compojure web application. When I sat down Larry was finishing up a card for a part of a messaging API. Specifically, message creation. You'd post to the controller and eventually your message would end up in the database. Compojure looks quite a bit like Sinatra. There was a simple block of functions that mapped routes and http methods to controller functions. These controller functions served the same purpose as actions do in Rails controllers.
Larry mentioned that the create method was getting a little out of hand. There were two conditionals that were essentially doing validation. If we got past the two conditionals a transform operation would execute and turn the form parameters into a Clojure data structure. We'd validate the record and if everything was fine it'd be persisted to the database. If validation failed or if either of the conditional guards failed the method would return a 422 response and a message.
I noted that the conditional guards were serving as as second type of validation. It was easy to move them into the clj-record validations and so we did. I also suggested to test that a system failure would return an appropriate response for an API - not some HTML 500 error page. We wanted to test this by throwing an exception out of the create action. We monkeyed around trying to get dynamic re-binding working through Clojure's binding form as a cheap form of mocking, but we couldn't figure it out. The day was over, so we tabled the test until tomorrow.
A note on my first day of Clojure experience. Personally, I find the language itself immensely pleasing to work with. As I've grown as a developer I keep finding myself writing smaller and smaller functions. A lot of languages have syntactic overhead that punish you for writing really small functions. Clojure does not, Ruby does not. I really like that.
However, Clojure is a young language and there are definitely rough edges. Naturally, the tools available in a young language are also necessarily young. There's a lot of missing pieces in Compojure that Rails has had baked in for years. Does that mean you shouldn't use Clojure or Compojure for your project? Absolutely not. But you should know what you're getting in to.
Now's the time to act if you want to make a name for yourself in the Open Source Clojure community. There's a ton of work to be done and not nearly enough people doing it.