In 2008 I discovered Clojure , and I was extremely excited to finally have an easy entry-way to Lisp. Pretty early on I wanted to get my head around one of Lisp's killer features: macros. A little playing around in the REPL was easy but not satisfying: I wanted to build something powerful. Having spent a few years doing Ruby on Rails , I thought ActiveRecord's macro-like capabilities ( has_many…
If you're implementing authentication in your web app on the server-side using some third party's OAuth, you ideally want to dedicate minimal system resources to waiting for HTTP responses. If you're working in Clojure , you can do this using Aleph 's asynchronous http client . Here I'll walk through using it to do server-side authentication with Facebook . [There's nothing auth-specific about…
I recently wanted to deploy a Clojure web app that allowed users to upload a CSV and work with the data. Heroku is as easy as it gets for web app deployment, but I figured I'd have to jump through some extra hoops to do the file upload. It turns out there are no hoops. Thanks to Heroku's ephemeral filesystem , we can handle file uploads just as we would on any other system, so long as we either…
After working fairly late last night I was too wound up to go to sleep when I got home. Something possessed me to start creating a little C# library providing a fluent interface for working with DateTime s, DateTimeOffset s, and TimeSpan s inspired by ActiveSupport's active_support/core_ext/numeric/time and related extensions. After about 3.Hours(30.Minutes()) the straightforward part had come…
On projects where you're integrating with legacy or vendor systems, it's often necessary to dedicate developers to technical analysis of the system before stories can be broken up reasonably and estimated by the team. Typically the output from that analysis is technical notes on a wiki page (or Mingle card). Those notes are helpful, but keep an eye out for the opportunity to do something far more…
I've been working in ActionScript lately. It's a bizarre language. Java-style OO features are smashed right on top of JavaScript, with no regard for the prototype-based inheritance that the language has had all along. (As far as I can tell Adobe doesn't want you to think about prototypes. I haven't dug into how the Java-style ActionScript class model plays with the prototype model, but it might be…
Last weekend at the ThoughtWorks US Away Day we were joined by Merrick Schaefer from UNICEF Innovation and a couple developers who've worked extensively with RapidSMS . RapidSMS is an open source project providing a set of libraries and apps for interacting with phones. It's been used for a variety of purposes, mostly in Africa, where cell phone coverage is far better than electricity or land-line…
If you like (1) interactive programming in Clojure from Emacs and (2) deploying to Google AppEngine, but you haven't yet managed to bring these two together, you should take a look at this post over at hackers-with-attitude , which walks you through setting up a pretty slick workflow.
Over the last few months ThoughtWorks has implemented several "Conference Connection" iPhone applications. They provide a view of the conference schedule, the ability to save a list of sessions you plan to attend, maps of the conferene site, a view of relevant Twitter posts, and some features specific to the various conferences. The Twitter integration includes a feature to post, launching your…
You could always define instance-specific behavior on Renum values the same way you can on any object in Ruby: enum : FakeWord do Foo () Bar () Baz () def extra_stuff " no extra stuff here " end end def Foo.extra_stuff " here's the foo stuff " end That works fine, but it's a little ugly. Starting this afternoon (with release 1.1) you can do this instead: enum : FakeWord do Foo do def extra_stuff "…
If you haven't already, you should check out Brian Marick 's Agile reboot: Artisanal Retro-Futurism Crossed With Team Scale Anarcho-Syndicalism . There's a video of his excellent presentation from Agile Roots if you don't feel like reading. There are also stickers you can ask for if you feel like spreading the word. It's totally tangential to the point, but my favorite quote from the video is near…
Last week at a ThoughtWorks home-office gathering in New York we had a presentation by one of Microsoft's Architecture Evangelists about their in-the-works cloud offering, Azure . I have to say I was pretty impressed. (If not for the whole Windows thing, I'd probably be trying it out instead of writing about it right now. If you aren't as bothered by Windows as I am, you can register and try it…
Chris O'Meara recently contributed a fix to make constantize_attribute handle nil values sanely . (Did you know "".constantize # => Object ? I was sure surprised.) He's using constantize_attribute to persist renum enumeration values in ActiveRecord models, which is the reason I wrote it in the first place. The reminder that these things do get used here and there inspired me to give renum a little…
I don't know why I didn't do this 3 months ago (or 5), but this morning I extracted find-by-sql from find-records so you can do arbitrary queries and still have them run through the callbacks defined for your model.
ActiveRecord migrations don't allow you to control column order when adding or changing columns. You can always just execute " ALTER TABLE ... " # but it's ugly and hard to remember the details. If you're willing to give up vendor neutrality, you can have the feature in pretty-Ruby-migration syntax with a small effort. Here's an implementation for MySQL that adds options :first and :after to…
Note: This post is quite old, and Compojure has changed (and gotten quite a bit bigger) since it was written. The basic steps for setting up a Clojure GAE app haven't changed much, but the Compojure bits may no longer be so simple. You can always just AOT-compile a Clojure HttpServlet to get a web app running. The release of Java support for Google AppEngine means more than just Java: it means…
Since clj-record started out as a sandbox for learning about Clojure macros , the project was a bit unstructured. Particularly weird was that the root source directory was the root of the project, so if you put that on your classpath, you also ended up with whatever random stuff was checked in at the top level on your classpath (for example TODO.txt and the script for running tests). That also…
I've just pushed clj-record support for attribute serialization to github . This uses clj-record callbacks and clojure.core's pr and read functions to allow you to store many standard Clojure and Java types as record attributes in varchar columns of your database. I'm not crazy about calling this feature "serialization" since it's not using Java's serialization mechanism (though I'm very happy…
Thanks to another contribution from Tunde Ashafa, clj-record now has support for more advanced queries using functions in the new clj-record.query namespace. Previously you could do this: ( manufacturer / find - records {: grade 98 } ) ; or ( manufacturer / find - records {: name " Humedai Motors " } ) Now you can do this: ; having required [clj-record.query :as q] ( manufacturer / find - records…
One of the first features I tackled in clj-record was a declarative validation API. Here I'll look at how it works, both in terms of how to use it and how it's implemented. How to declare validations The init-model form can include an option-group that opens with the keyword :validation like this. ( clj-record . core / init-model (: validation (: nickname " Nickname is required. " # ( not ( empty…
In case you missed the announcement , RSpec now supports this badassery. describe Person do describe " born 19 years ago " do subject { Person . new ( : birthdate => 19 . years . ago } it { should be_eligible_to_vote } it { should be_eligible_to_enlist } it { should_not be_eligible_to_drink } end end
I've spent a chunk of the last month (and an absurd amount of the last four days) working on clj-record : an ActiveRecord-like library written in the Clojure programming language. (Clojure is a LISP dialect with badass concurrency features for the JVM.) clj-record aims to provide an idiomatic "functional" API for persistence with many of the features we've come to appreciate from ActiveRecord,…
Ack in Project is probably the TextMate bundle I use the most (after the Ruby bundle, I suppose, which I constantly use without even thinking about it). If you haven't already, you should install it immediately for very fast project searches (and recursive searches of just the selected directory, which on its own is hugely useful). What it took me a while to realize, though, is that my project's…