Wednesday, September 2, 2009

New Home

After a long period away from this blog as I took a 3 month vacation from programming to travel through Guatemala, I'm back. However, I will no longer be maintaining this blog on blogger; if you are interested in reading more content by me about ruby, rails, or startups please drop by

Tuesday, April 28, 2009

Using inject for improved performance

I found myself wanting to know if an array had any truth values in it, and wrote a method that I was pretty proud of:
module Enumerable
  def any_true?
    inject(false) do |truth, item|
      truth || (yield item)
So now I can write
arr.any_true? {|item| some_method(item)}
Then I realized that a simpler way of expressing this is just {|item| some_method(item)}.any?

The latter seems a lot better... its easier to understand, and uses just ruby primitives. But the first is actually still better for most cases. Why? Performance. Imagine some_method includes a database query or two... In the simple map.any? case we'll have to evaluate it for every item. But in the any_true? case we only evaluate until we find one, at which point we're done; we'll short circuit every other check and never hit the method again.

The difference can be enormouse. If I emulate this database requirement using a method that looks like:
def random_truth(likelihood)
    sleep 0.1
    rand < likelihood
I can now run some tests that demonstrate the extreme difference in runtime:
>> Benchmark.realtime {10.times { (1..100) {|i| random_truth(0.5)}.any? }}
=> 100.000391960144
>> Benchmark.realtime {10.times { (1..100).to_a.any_true? {random_truth(0.5)} }}
=> 2.00004100799561

Friday, April 17, 2009

Distributed computing and Ruby

At work, I've been spending a lot of time working on porting our log management and analysis system over from a dying mysql implementation to a new system build upon an open source distributed database (Hypertable) using distributed Map/Reduce jobs for a variety of summarization and analysis tasks.

I've been amazed and gratified to be able to do the vast majority of this work within the comfort of Ruby, my favorite language. While Hypertable is written in C++, it uses Thrift to provide ruby and other language access, and since the primary developers of Hypertable are at Zvents (a rails shop), they've created a Rails plugin called HyperRecord that allows us to access Hypertable almost identically to how you would access mysql with ActiveRecord.

This has resulted in the ability to make the front end application for our stats & logging infrastructure a standard Rails app. Access restrictions are somewhat different in Hypertable than in a full relational database (its easiest to think of as an ordered hash... lookups by key or for a range of keys are supported, but conditions are expensive), but for most of our developers its just another rails app to work with.

The second place where I've been amazed by how much I've been able to stick to ruby is in designing and running our batched Map/Reduce jobs. We're using a framework called Cascading for designing our scalable batch workflows, built in Java and sitting on top of Hadoop. For those who aren't familiar, Hadoop is an open source implementation of Map/Reduce, written in Java, and Cascading allows for a higher-level conceptual model for parsing, analyzing, and modifying your data using Hadoop.

Cascading provides a number of built in filtering, text processing, and arithmetic map/reduce operations built in, and thanks to the wonder that is jruby, we're able to arrange our workflows entirely within ruby using Cascading.jruby. Only when we need a special operation that can't be constructed from the built-ins do we have to dip into Java.

So if you've been itching to dip your toes in the open source distributed computing revolution, but have been reluctant due to the Java heavy nature of Hadoop, take a look at HyperTable and Cascading!

Sunday, March 15, 2009

A new appreciation for convention over configuration

At work, I'm working on revamping our logging infrastructure to use Hypertable (an opensource Bigtable clone) for storage, and Hadoop (an opensource Map/Reduce framework) for log processing.

I'm extremely excited about the potential these tools have for allowing us to do all sorts of ridiculously cool analyses on our logs, and at some point I'll write about some of the things we are doing with them. However, in the meantime I just wanted to share my renewed appreciation for the simplicity of convention over configuration that I've gotten used to with Rails.

You see, Hadoop is written in Java, and uses Apache Ant for builds. We're talking 60-100 line XML files for to configure simple example jobs. Why would anyone voluntarily set their system up this way? To paraphrase one of my coworkers... enterprise-quality appears to be roughly translatable as 'over-engineer everything'!

Tuesday, February 24, 2009

Flash of Insight about Prototypal Inheritance

I've always been confused about how JavaScript inheritance worked, and what
all of these prototype things actually are. Reading article after article after article about prototypal inheritance gave me some more details about how to use it, as well as opinions on its value, but the fundamental model was still missing. But on the train this evening I was reading through the Wikipedia article on Prototypal inheritance when suddenly I had a flash of insight! The reality is so much simpler than anything I'd imagined. Without further ado, here it is:

A prototype is an object to be copied. Thats it. When you create a new object in a prototypal language, it starts out as a copy of its prototype.

Its common to see javascript that looks something like:

function A(){};
A.prototype.method1 = function() {foo};
A.prototype.method2 = function() {bar};
A.prototype.method3 = function() {blah};

Now any new instance of A will have method1, method2, and method3 defined. I guess I'd always thought of this as some sort of magic. But really, its equivalent to

function B(){};
B.method1 = function() {foo};
B.method2 = function() {bar};
B.method3 = function() {blah};
A.prototype = B;
function A(){};

In other words... here's this object B, it has these methods. When you create an object of type A? Just copy B. So simple! So flexible! Why did I not understand this before?

There is, of course a caveat. In JavaScript, we aren't really copying the methods, as that would be incredibly inefficient. There is a hidden pointer (accessible in some browsers as A.__proto__) that points back to the prototype, and the runtime then takes care of delegation. But conceptually, its just a copy.

Sunday, February 1, 2009

Name change & feedback request

I realized that the original name I had for this blog (Ruby, Rails, and other coding thoughts...) was not turning out to be representative of what I was posting. I've been writing almost entirely Shoes related content, with a few divergences into process related things and other microframeworks.

So I've decided to change the name to something more representative of what I'm using this blog for: writing about the coding related stuff I'm doing for fun. Since I develop a Rails app for work (this app, company blog here), I've been doing very little playing with Rails outside of work.

The new name, 'Ruby Merriment', expresses more clearly what this is about. Having fun playing with my favorite programming language.

That said, one thing I'm excited about is trying to engage in an ongoing conversation with other people who are excited about Ruby. I'm not quite clear what sets of things I write about are interesting to other people; It might be interesting to explore some more Rails related ideas, if people want to talk about those. So give me some feedback: Do you like what you're reading? Are there other things you'd like to talk about? If you have a blog where you talk about coding, point me at it so I can take a look and respond.


Saturday, January 31, 2009

More Shoes Structure

When I first started using Shoes, it took me a while to get the various pieces set in my head. There's a couple of different levels to understand. There are a number of tutorials about layout, the most fundamental being Stacks and Flows. This is critical to understanding to design your GUI, but it wasn't enough for me to really understand what was going on.

After hacking around, reading through the source code, and writing some addons I think I'm starting to get my head around it, so here's an attempt to explain some more of the structure of Shoes.

The most basic piece is This is the method you use to open a window for a new Shoes application; hello world in shoes is something like. do
para "Hello World"

What this does is twofold... it instantiates a new Shoes::App object, and sets self inside the block to point to that object. The Shoes::App object provides all of the helper methods for creating different components, such as para, button, stack, flow, etc, and is responsible for actually rendering them. The objects themselves don't render, they just define a structure that the Shoes::App object will then render. This is why, when trying to do something in a module or class outside of the block, you need to pass in the app object, or access it through the app method on some already rendered object (all shoes objects have an app method to get back to the app they are rendered in).

How does the structure that Shoes::App builds up look? It is a tree format, that actually looks remarkably similar to the DOM in the web world.

At the root of the tree is the slot associated with the original Shoes::App object. This slot behaves like a flow, and can be accessed via the slot method on the Shoes::App object; within the block that would be self.slot. (This is important; after reading that the app object was a flow, I originally thought I'd be able to use all of the flow methods immediately on it, but you actually need to call them on self.slot.)

Every node in the tree has an accessor called parent and one called children. Lets examine what these look like in the hello world example above, by adding some debug output:

app = do
para "Hello World"
Shoes.debug "Parent is #{app.slot.parent.inspect}"
Shoes.debug "Children are #{app.slot.children.inspect}"

The console now shows:

which is pretty much what we'd expect. The root should have no parent, and the paragraph is pretty much the only element, so it should be the first child. What does that paragraph look like? Lets try do
p = para "Hello World"
Shoes.debug "Para Parent is #{p.parent.inspect}"
Shoes.debug "Para Children are #{p.children.inspect}"

Now we see:

The parent is pointing back to the app.slot (which we now see is not actually a flow, but an instance of the Shoes class, which flows inherit from.) And the children of a Para object actually contain the text of the paragraph.

Understanding this tree structure was one of the biggest breakthroughs for me, because it means that many of the things I know from manipulating the DOM with javascript in the web world are suddenly applicable to Shoes. I'm no javascript genius, but I have already climbed some of the learning curve there, and being able to apply that to Shoes was eye opening.

One of the things the DOM does really well (and the Shoes model should as well) is allow you to navigate, find, and manipulate things that have been generated someplace else. This is where I got the idea for ShoeQuery, and will prove extremely useful in my efforts to build a Shoes debugger.

I think this similarity could make Shoes the toolkit of choice for web developers coming to the desktop.

Thursday, January 29, 2009

Event Handler chains in Shoes

One of the beautiful things about Shoes is how simple and easy it is to set up event handlers on objects. As I talked about in a previous post creating a handler on a button is as simple as

b = button "Click Me" { alert "You clicked the button" }

This is great for simple things, but I hadn't been hacking on Shoes for very long before I wanted to do more than this. In particular, since one of my projects is creating an application to preview Shoes applications, I wanted to be able to add handlers that call back into my main application without worrying about their effect on the code being previewed.

To do this, you need to be able to have multiple handlers on an element at once, so that you can add new event handlers without disturbing the existing ones. I spent a while trying to understand the c-based implementation of event handlers, and figuring out all of the things I'd have to do to change it to a chain based implementation, but then realized that given the ruby nature of Shoes, this was a prime opportunity for monkeypatching.

Monkeypatching may be a little less performant, but this is for a debugger-style thing anyway (I'm thinking I want to get to something a lot like Firebug is for web development...), so who cares if its slow?

So in I dove. I'm calling the module ShoeShine, because its cleaning up my Shoes without changing the inside at all, and it turned out to be pretty simple to implement. First, I define a few methods to add, remove, and call handlers:

def add_handler(type, &block)
@_handlers ||= {}
@_handlers[type] ||= []
@_handlers[type].push block
# set up callbacks from old handlers invocation into
# new handler chain
self.send "#{type}_without_chains".to_sym do |*args|
self.call_handlers(type, *args)

def clear_handlers(type)
if @_handlers
if @_handlers.delete(type)

def call_handlers(type, *args)
return unless @_handlers[type
@_handlers[type].each do |block|*args)

Then I do some metaprogramming and monkeypatching to plug this in between handler registration and handler callback:

HANDLERS.each do |handler|
eval %(
def #{handler}_with_chains(&block)
# need to clear handlers to maintain old semantics
add_handler(:#{handler}, &block)

def self.included(klass)
klass.instance_eval do
ShoeShine::HANDLERS.each do |handler|
if klass.instance_methods.include? handler.to_s
# Replace old handlers with new handlers
alias_method "#{handler}_without_chains".to_sym, handler
alias_method handler, "#{handler}_with_chains".to_sym

Finally, I include this module into all interesting Shoes classes:

Shoes.constants.each do |c|
k = Shoes.const_get(c)
if k.is_a? Class
k.send :include, ShoeShine

Voila! Suddenly, as well as having the traditional Shoes interface to handlers, you can also add additional handlers onto existing objects without disturbing the originals. This will open the door to all sorts of interesting things. I've already mentioned my intent to use this for debugging, but I'm also exploring using this as a way to get around the current Shoes limitations on click, hover, leave, etc handlers of only working on slots, allowing them to trickle down to paragraphs, widgets, etc.

I've got some early versions of this working, but its definitely not ready for prime time yet. For any who are interested, you can find both the ShoeShine code and my early trickle down work at github in the shoes-preview tree.

Sunday, January 25, 2009

Can I just say how much I love method_missing?

I wanted to follow up on my previous explorations with ShoeQuery to add some helper methods to access pieces of shoes functionality... thinking I'd have to add pieces one by one. However, it turns out that due to the magic of method_missing, I was able to add access to basically all of them with a single 22-line method. It looks like:

def method_missing(method, *args, &block)
if args.empty? && !block_given?
# if you have no arguments and no block, think of it as a query
# and return the answer for the first element.
if first.respond_to? method
return first.send(method)
elsif block_given?
each {|elem| elem.send(method, *args, &block)}
# Otherwise, think of it as a setter
setter = "#{method}=".to_sym
if first.respond_to? setter
each {|elem| elem.send(setter, *args, &block)}
each {|elem| => args[0], &block)}

And now, thanks to this I can write lines in shoes as follows:

# find all paragraphs, change their text to 'all ps', and color
# them red
shoe_query('para').text("all ps").stroke(red)

# replace the click handlers on all buttons
shoe_query('button').click do
para "All your button are belong to us now

Introducing ShoeQuery

ShoeQuery (better name needed) was born out of a desire to be able to find and manipulate elements in Shoes without having stashed away their locations ahead of time. It was inspired by jQuery's mechanisms for finding and manipulating DOM objects in Javascript.

The fundamental object (a ShoeQuery object) is pretty much an array of Shoes Elements, augmented with some extra functions. ShoeQuery objects are created via a helper (unsurprisingly named shoe_query) that lives in the Shoes::App object, and so should be accessible anywhere you want it. You can pass into that helper a selector, and it will return a ShoeQuery object containing the elements that match. You can also pass in an array of elements you already have handy, or an existing element, and it will also return a ShoeQuery object containing those elements. This form should be familiar for those who've used jQuery.

Right now, the things it lets you do are pretty limited, though a lot of the functionality jQuery specially provides already exists in Ruby. The one big feature is the ability to find elements by type, including css-like hierarchy. You can do this either by invoking shoe_query directly, or calling find on an existing shoe_query object (to search within its children). For example, given the demo app:

load 'shoe_query.rb' do
app = do
para "foo"
f = flow do
stack do
para "bar"
para 'blah'
b = button "click me to change all paragraphs" do
shoe_query('para').each do |p|
p.text = "all ps"
b2 = button "click me to just change the paragraphs inside the flow" do
shoe_query('flow').find('para').each do |p|
p.text = "flow ps"
b3 = button "click me to change the button inside the stack" do
shoe_query('stack para').each do |p|
p.text = "stack p"


In this case, the first button modifies all three paragraph elements, while the latter two use two different mechanisms to scope their changes to within the flow and within the stack respectively

As I play with this more, I'll be extending it to include more functionality. Let me know if there's anything you want!

You can get ShoeQuery at github at

Friday, January 23, 2009

Shoes Class Hierarchy Redux: Introspection

After writing up the Shoes class hierarchy, someone pointed out that this is already included in the Shoes manual (and available online here. I took a look, and found some disagreements between that class hierarchy and the one I had come to. In particular, large numbers of classes are listed a being subclasses of Shoes::Basic, including some like EditBox and EditLine that are very definitely subclasses of Shoes::Native.

My first thought was that the manual must be just out of date, but upon looking into the source for the manual (located in the shoes source at lib/shoes/help.rb, as well as static/manual.txt), I discovered that the class hierarchy was actually being generated dynamically by introspecting the Shoes classes in the following method:

def class_tree
tree = {}
Shoes.constants.each do |c|
k = Shoes.const_get(c)
next unless k.respond_to? :superclass

c = "Shoes::#{c}"
if k.superclass == Object
tree[c] ||= []
k.ancestors[1..-1].each do |sk|
break if [Object, Kernel].include? sk
(tree[] ||= []) << c
c =

This code takes the constants defined in Shoes, looks for those that have superclasses, and pulls out their ancestors up until Object. Why, then, if the manual is being generated dynamically, does it miss the fact that Shoes::EditLine, Shoes::EditBox, and a host of others inherit from Shoes::Native?

To debug this, I took a look at the ancestors tree of Shoes::EditBox using the shoes preview app I wrote about here, entering

Shoes.debug Shoes::EditBox.ancestors.inspect

and clicking 'Run Without App'. In the error message text box, the class hierarchy of Shoes::EditBox appeared:

[Shoes::EditBox, Shoes::Basic, Shoes::Native, Object, FileUtils, FileUtils::StreamUtils_, Kernel]

Shoes::Basic is definitely the first ancestor... but in the declaration of the EditBox class, Shoes::Native was clearly the ancestor:

(From shoes/ruby.c line 4965)

cEditBox = rb_define_class_under(cShoes, "EditBox", cNative)

What's going on? The moment of inspiration came when I looked at the definition of Shoes::Basic in lib/shoes.rb. Basic is defined as a module within the Shoes class, and then included on a large list of classes. What I'd forgotten was the way that Modules exist in the Ruby inheritance chain. When a module is included, it creates a pseudo-class known as an Iclass that sits directly above the including class in the inheritance chain, and points to the module's methods. Thus by including a module, you are changing around the ancestors of your class. A good reference can be found here, and a quick quiz to test your knowledge here.

Including modules in the display of the hierarchy might be desirable, but I'm not sure at all how to do it. By doing so, instead of having a nice tree form, suddenly we have a DAG,
which is a much more complex structure to display. Both the introspection code and display code currently expect a tree, so this is the source of the errors/lack of completeness in the current manual.

Its not clear how useful having the modules displayed in the hierarchy is, either. The Shoes::Basic module doesn't do very much, its much more useful to know which classes are descended from the Shoes::Native class.

So the simple fix, to change the manual to showing what you might expect, is to add a single line to the loop over ancestors, skipping modules.

k.ancestors[1..-1].each do |sk|
break if [Object, Kernel].include? sk
+ next unless sk.is_a? Class #don't show mixins
(tree[] ||= []) << c
c =

Now the introspected class hierarcy looks exactly like the hierarchy I constructed by hand. I've pushed the change to my fork of shoes on Github. Dunno when/if they'll get merged.

If someone wants to do the more complex fix of changing the structure and display to be a DAG, go for it!


If anyone knows a way to get syntax highlighting for ruby code snippets on blogger, please let me know! Thanks!

Tuesday, January 20, 2009

Leaning Into Distractibility

Some days, I'm able to focus for hours without distraction, getting my head completely into the problem I'm working on, and nothing short of the building collapsing will pull me out of it.

Other days, the slightest passing thought or noise distracts me, and I'm constantly checking my email, opening news sites or blogs in new tabs, and getting up to get snacks or drinks.

Today was one of those distractible days. After watching the inauguration in the morning, my mind was abuzz with thoughts about politics, the economy, the future... pretty much anything but work.

I've tried a few mechanisms for dealing with days like this, before finally landing on one that seems to work and results in me still getting things done. I've tried to power through it, and work on exactly what I otherwise would have worked on, but distractions pop me out of my mental constructions, and I have difficulty solving big problems. I've tried leaving work for some time to allow myself to be distracted, but this almost never results in a quick return to productivity.

The final approach, which I used today, is to take advantage of the distractibility to deal with all of the small niggling tasks that have been building up over time. Tiny and annoying tasks lend themselves to distraction regardless of mood. There is a natural breath after the completion of any task, so even when feeling focused, a series of small tasks lends itself to more interruption and wasted time than a single larger task. When I'm in a distractible mood, I'm going to be wasting that time anyway, so its an ideal time to get rid of these annoyances without detracting from what I could be getting done.

So instead of making progress on my larger tasks, today I spent my time on a myriad of small tasks. I investigated a number of reports from our support team, fixed a few bugs I found with that, refactored some controller logic for our Birthday Cause feature to make it easier to reorder pages in various flows, merged in a lingering branch of cleanup from our last fixit day, and made a number of other small tweaks, fixes, etc.

None of these was very big, none of them very interesting, but all needed to get done at some point. By leaning into my distractibility instead of fighting with it, instead of a wasted day I'm going home with a list of things I no longer need to worry about.

Cross-posted from my company's engineering blog:

Saturday, January 17, 2009

Exploring the Shoes class hierarchy

I've spent a lot of time this week attempting to get to know the Shoes ruby GUI kit better. Shoes is an open source project, and one that is pretty early in its evolution.

This has a couple of implications:

  1. Its very raw. It doesn't take too much tinkering to find something thats broken.

  2. It is incomplete. Shoes has a few fundamental abstractions that make basic layout straightforward, and generally makes simple things simple. However, if you try to do something that _why hasn't tried to do yet, it probably won't work.

  3. You can open it up, learn how it works, and fix things!

I've spent most of my train/commute time (3 hours a day) this week digging into the source, fixing minor bugs, and trying to understand how it all works. While Shoes is a ruby toolkit, most of it is written in C. From what I've been able to determine, there are essentially three layers.

The uppermost layer is the set of Ruby classes and their methods, most defined in C and then exposed to Ruby. These live in lib/shoes.rb, the various files in lib/shoes, shoes/ruby.[ch], and shoes/canvas.[ch].

Below that there is a set of abstract windowing code. This defines the way that Shoes layouts occur, how the different objects relate to each other within the visible canvas, etc. This is located primarily in shoes/app.[ch] and shoes/world.[ch]. Also living in this middle layer are things like image handling, http handling, and special effects.

Finally, the bottom layer is the interface to the native graphics libraries... a gtk interface, a windows interface, and an interface to Cocoa for OS X. These are located in shoes/native.h and the shoes/native directory. These are typically called into from the middle layer, and issue event-related callbacks back up into the middle layer.

As I learn more about Shoes, I hope to understand and write about all of these pieces, but for now I'm focusing most on learning about the interface Shoes exposes to ruby. This allows me to better make sense of what works and what doesn't, and gain an intuition for how things should work in Shoes programs. Since a lot of the code is written in C, I've spent some time figuring out just the Ruby class hierarchy.

Here's the basic hierarchy... I haven't included anything about what methods are defined on what classes here, but I've put my notes at if you want to look at them. I'll probably update them as I do more learning.

class Window; end
class Mouse; end
class Canvas; end
class Shoes < Canvas
# Canvas-like things
class App < ::Shoes; end
class Flow < ::Shoes; end
class Stack < ::Shoes; end
class Mask < ::Shoes; end
class Widget < ::Shoes; end

# Standalones with no children
class Shape; end
class Effect; end
class Video; end

# Patterns
class Pattern; end
class Background < Pattern; end
class Border < Pattern; end

# TextBlocks
class TextBlock; end
class Para < TextBlock; end
class Banner < TextBlock; end
class Title < TextBlock; end
class Subtitle < TextBlock; end
class Tagline < TextBlock; end
class Caption < TextBlock; end
class Inscription< TextBlock; end

# Text
class Text; end
class Code < Text; end
class Del < Text; end
class Em < Text; end
class Ins < Text; end
class Span < Text; end
class Strong < Text; end
class Sup < Text; end
class Sub < Text; end
class Link < Text; end
class LinkHover < Text; end

# Natives
class Native; end
class Button < Native; end
class EditLine < Native; end
class EditBox < Native; end
class ListBox < Native; end
class Progress < Native; end
class Check < Native; end
class Radio < Native; end

# Timing related stuff
class TimerBase; end
class Animation < TimerBase; end
class Every < TimerBase; end
class Timer < TimerBase; end

class Color; end

class Download
class Response; end

# Errors
class InvalidModeError < StandardError; end
class NotImplementedError < StandardError; end
class VideoError < StandardError; end

So at least now I know that if I've figured out something that works pretty well flows, it should work for stacks or the entire app as well. Similarly if I'm comfortable working with para, its likely similar techniques will work for banners, titles, subtitles, captions etc.

Its a work in progress; let me know if I got anything wrong, or if you want to know more about the methods available for each class.

Sunday, January 11, 2009

Running with shoes

I've been playing off and on with Shoes for the last couple of weeks. Shoes is a simple ruby GUI toolkit designed for beginners. It seems like a really cool way to do the GUI aspects of simple desktop applications, designed to reduce the barriers to entry.

Instead of the intimidating scope of something like learning the GTK API, with Shoes you only need to learn a few core abstractions, and you're off and running with simple and beautiful code.

Want to add a button? Its as simple as

button "My Button"

To add a handler on that button?

b = button "My Button" do
alert "You clicked my button!"

I'm pretty excited about playing with this. Unfortunately, however, the framework is very young and still pretty buggy. Documentation is reasonably good, but definitely incomplete. I'm trying to get a development environment together so I can debug some of the problems in the framework that I've run into, but so far have been unsuccessful at building a working version of Shoes; I get a mostly functioning version, but the text is showing up as boxes. I think I'm getting something wrong in the dependencies... I dunno. I've got a question in to the mailing list about this, so we'll see what happens.

In the meantime, I've built a little tool to make my turnaround time for testing how shoes code will look a bit faster. Shoes Preview lets you enter code & see what it will look like all without restarting Shoes. Its still pretty clunky, but already speeding me up from the modify/save/reopen cycle that I had been using. If you try it out, feel free to send me patches or suggestions! Happy hacking!

Sunday, January 4, 2009


I started playing with Camping yesterday. Camping is ruby web microframework with the explicit goal of taking less than 4k of space. This implies a sparse, simple interface, and for those (like me) who are fitting their web apps into a 256M slice at slicehost, makes for much less memory usage than a rails app, or even a merb app. The idea is that for a simple application, rails is overkill. I'm thinking of it as a way to build json-accessible REST microapps.

I really like the simplicity of routes being defined with a regular expression right at the controller definition.

module Hello::Controllers
class Index < R '/', '/snips'
def get
@snippets = Snippet.find :all
render :index

That said, it took me more code than I would have liked to get a CRUD interface for a simple model. Not even looking at the views, here is the controller code I ended up with:

module Hello::Controllers
class Index < R '/', '/snips'
def get
@snippets = Snippet.find :all
render :index
class New < R '/snips/new'
def get
@snippet =
render :new
def post
snip = Snippet.create(:title => input.title,
:body => input.body)
redirect Show,
class Show < R '/snips/(\d+)'
def get(id)
@snippet = Snippet.find(id)
render :show
class Edit < R '/snips/edit/(\d+)'
def get(id)
@snippet = Snippet.find(id)
render :edit
def post(id)
Snippet.find(id).update_attributes(:title => input.title,
:body => input.body)
redirect Show, id

I'd like to make this a little tighter, and make it a little more purely RESTful (especially for my idea of using these as REST-based microapps), but I'm not sure the right way to do that yet. Camping doesn't inherently have anything like the rails _method hack for the missing put/delete http verbs, and the only thing googling has been able to turn up is a plugin that hasn't been touched in over a year called Sleeping Bag. I'll take a look at that and see how it goes.