Code

You are currently browsing the archive for the Code category.

A quick RVM rundown

(It so happens I’m presenting this at Dallas.rb tonight. Hopefully it can also be useful to those out in internetland too.)

RVM gives you three things:

  • an easy way to use multiple versions of multiple Ruby VMs
  • the ability to manage multiple indpendent sets of gems
  • more sanity

First, let’s install RVM:

  • gem install rvm
  • rvm-install
  • follow the directions to integrate with your shell of choice

Now, let’s install some Rubies:

  • rvm list known will show us all the released Rubies that we can install (more on list)
  • rvm list rubies will show which Rubies we have locally installed
  • rvm install ree-1.8.7 gives me the latest release of the 1.8.7 branch of Ruby Enterprise Edition
  • rvm install jruby will give me the default release for JRuby
  • rvm use jruby will switch to JRuby
  • rvm use ree will give me Ruby Enterprise Edition
  • rvm use ruby-1.8.6 will give me an old and familiar friend
  • rvm use system will put me back wherever my operating system left me

The other trick that RVM gives us is the ability to switch between different sets of installed gems:

  • Each Ruby VM (JRuby, Ruby 1.9, Ruby 1.8, REE) has its own set of gems. This is a fact of life, due to differing APIs and, you know,
    underlying languages.
  • rvm use ruby-1.9.1 gives you the default Ruby 1.9 gemset
  • rvm use ruby-1.9.1%acme gives you the gemset for your work with Acme Corp (more on using gemsets)
  • rvm use ruby-1.9.1%wayne gives you the gemset for your work with Wayne Enterprises
  • rvm use ree%awesome gives you the gemset for your awesome app
  • You can export and import gemsets. This can come in handy to bring new people onboard. No longer will they have to sheepishly install
    gems on their first day as they work through dependencies you long
    since forgot about.

Some other handy things to peruse:

I also promised you some extra sanity:

  • RVM knows how to compile things, put Rubygems and rake in place, even apply patches and pull from specific tags. You can do more important things, like watch The View or read an eleven part series on pre-draft analysis for the Cowboys.
  • RVM lets you isolate different applications you’re working on. Got one app that doesn’t play nice with Rails 2.x installed? No problem, create a gem environment for that! Stuck in the spider-web of Merb dependencies? Isolate it in its own environment.
  • RVM makes multi-platform testing and benchmarking easy. You can easily run your test suite or performance gizmo on whatever Rubies you have installed.
  • RVM makes it easy to tinker with esoteric patchlevels and implementations. For instance, feel free to tinker with MagLev or the mput branch of MRI.

A couple other things RVM tastes great with:

  • Using homebrew to manage packages instead of MacPorts
  • Not using sudo to install your gems
  • Managing your dotfiles on GitHub

Tags:

(For the impatient: skip directly to the `attribute_mapper` gem.)

In the past couple months, I’ve worked on two different projects that needed something like an enumeration, but in their data model. Given the ActiveRecord hammer, they opted to represent the enumeration as a has-many relationship and use a separate table to represent the actual enumeration values.

To a man with an ORM, everything looks like a model

So, their code ended up looking something like this:

class Post < ActiveRecord::Base
 
  belongs_to :status
 
end
 
class Status < ActiveRecord::Base
 
  has_many :tickets
 
end

From there, the statuses table is populated either from a migration or by seeding the data. Either way, they end up with something like this:

# Supposing statuses has a name column
Status.create(:name => 'draft')
Status.create(:name => 'reviewed')
Status.create(:name => 'published')

With that in place, they can fiddle with posts as such:

post.status = Status.find_by_name('draft')
post.status.name # => 'draft'

It gets the job done, sure. But, it adds a join to a lot of queries and abuses ActiveRecord. Luckily…

I happen to know of a better way

If what you really need is an enumeration, there’s no reason to throw in another table. You can just store the enumeration values as integers in a database column and then map those back to human-friendly labels in your code.

Before I started at FiveRuns, Marcel Molina and Bruce Williams wrote a plugin that does just this. I extracted it and here we are. It’s called attribute_mapper, and it goes a little something like this:

class Post < ActiveRecord::Base
  include AttributeMapper
 
  map_attribute :status, :to => {
    :draft => 1,
    :reviewed => 2,
    :published => 3
  }
end

See, no extra table, no need to populate the table, and no extra model. Now, fiddling with posts goes like this:

post.status = :draft
post.status # => :draft
post.read_attribute(:status) # => 1

Further, we can poke the enumeration directly like so:

Post.statuses # => { :draft => 1, :reviewed => 2, :published => 3 }
Post.statuses.keys # => [:draft, :reviewed, :published]

Pretty handy, friend.

Hey, that looks familiar

If you’ve read Advanced Rails Recipes, you may find this eerily familiar. In fact, recipe #61, “Look Up Constant Data Efficiently” tackles a similar problem. And in fact, I’m migrating a project away from that approach. Well, partially. I’m leaving two models in place where the “constant” model, Status in this case, has actual code on it; that sorta makes sense, though I’m hoping to find a better way.

But, if you don’t need real behavior on your constants, attribute_mapper is ready to make your domain model slightly simpler.

Tags: ,

Testing declarative code

I’m a little conflicted about how and if one should write test code for declarative code. Let’s say I’m writing a MongoMapper document class. It might look something like this:

class Issue

  include MongoMapper::Document

  key :title, String
  key :body, String
  key :created_at, DateTime

end

Those key calls. Should I write a test for them? In the past, I’ve said “yes” on the principle that I was test driving the code and I needed something to fail in order to add code. Further, the growing ML-style-typing geek within me likes that writing tests for this is somewhat like constructing my open wacky type system via the test suite.

A Shoulda-flavored test might look something like this:

class IssueTest < Test::Unit::TestCase

  context 'An issue' do

    should_have_keys :title, :body, :created_at

  end

end

Ignoring the recursive rathole that I’ve now jumped into, I’m left with the question: what use is that should_have_keys? Will it help someone better understand Issue at some point in the future? Will it prevent me from naively breaking the software?

Perhaps this is the crux of the biscuit: by adding code to make certain those key calls are present, have I address the inherent complexity of my application or have I imposed complexity?

I’m going to experiment with swinging back towards leaving these sorts of declarations alone. The jury is still out.

Tags:

A bumpy subway wall, loving things for their Unix-y qualities, Kurt Vonnegut looking dapper, the final movement of Dvorak’s Ninth Symphony (originally his fifth), and a music video by Talib Kweli that makes me want to go get my hair cut. Oh, and I can’t leave out the connection between prototyping physical things and applications operating on large data, Ben Scoffield’s take on database taxonomy and a screed on reading one book per week.

(Editor’s note: I recently took to using Tumblr again. For a while, I’ve been curating interesting stuff here. But Tumblr has evolved into a really fantastic application for doing this. So, my policy going forward is to post my stuff here and curate other people’s awesome stuff over there. That said, I’ll probably do “best-of” posts, like this one, to keep you interested and informed.)

Time is the New Memory:

The time problem is not easy to see in today’s mainstream languages because there are no constructs that make time explicit. It is implicit in the system. We don’t even know that’s what we’re doing when we use locks to try to make this work.

I’ve been thinking about how we represent time in programs for a while. The problem is that concurrent programs are all about time, but mostly, we only use two mechanisms to represent it in our programs.

The semi-explicit way is through locks. When we insert locks around some bit of code, we are giving hints to the system that things should only proceed in a certain order. This ordering gives us a notion of time, but it’s not horribly comforting.

The completely implicit way we represent time in our programs is by ordering calls to functions and the lines of code within those functions. Line 10 always executes before line 11, etc.

The problem that Rich Hickey, who has some fantastic ideas about this time stuff, has in the article I quoted is that time is managed manually and implicitly. When you start writing large concurrent programs, this falls apart. We need better constructs to deal with it.

Think of it like the shift from unstructured programming to structured programming to object-oriented programming. At first we just had a long code listing; no functions, just line after line of code. This became mentally untenable, so we shifted to structured, procedural programming. But some of our data was global and it was often hard to tell what functions belong to what data. So we moved to object-oriented programming and encapsulation.

Hopefully Rich Hickey, Simon Peyton-Jones and other functional programming folks can lead us to is a nice way to structure our programs around time. I’m eager to have my brain melted by what they conjure up.

Tags:

Polyglot persistence:

I think that many of the NoSQL crowd either fail to either recognize, or to properly describe that their preferred databases don’t replace applications like MySQL and Postgres, just as Ruby doesn’t replace Java. Instead, the explosion of these new options for persistence just work better for some domains (and worse for others).

Ben Scofield’s spot-on here. One of the many transitions we’re undergoing is from “I’ll use MySQL most of my career” to “I’ll tinker with a different database for every project over a couple years and then pick and choose the best as time goes on”.

Tags:

Tons of FP fun

A programming language zoo, a week of FP heaven, rewriting PHP with Haskell and a game for kids of any age to learn the untyped lambda calculus. Did I ever mention it’s a good time to have a fascination with functional programming languages?

Tags: ,

Almost five years ago, we were witness to the reinvention of web frameworks. A couple upstarts named Django and Rails appeared at almost the same time, espousing many of the same values. In the typical Gandhi-cycle, they were first ignored, the incumbents fought them, and then they achieved victory over the incumbents. Today, any framework that’s used on new projects is likely to have more than a hint of Django and Rails in it.

Today, we’re seeing the same thing for databases. Something is going on and things are changing. Barring an unprecedented departure of fashion from software development, I’ll look back five years from now and write about some other shift in the development landscape.

But, all shifts like this need a name. Right now, the best we have is NoSQL. The problem with that name is that it only defines what it is not. That makes it confrontational and not amazingly particular to what it includes or excludes.

Damien Katz, the creator of CouchDB, has noted the need for a better name for this storage revolution. Allow me to proffer mine:

Post-relational

What we’re seeing its the end of the assumption that valuable data should go in some kind of relational database. The end of the assumption that SQL and ACID are the only tools for solving our problems. The end of the viability of master/slave scaling. The end of weaving the relational model through our application code.

We’re seeing an explosion in the ideas about how one should store important data. We’re looking at data to see if it’s even worth persisting. We’re experimenting with new semantics around structure, consistency and concurrency.

In the same way that post-modernism is about reconsidering the ways of the past in art and architecture, post-relational is a chance for software developers to reconsider our own ways. Just as post-modernism didn’t invalidate the entire history of art, post-relational won’t invalidate the usefulness of relational databases.

However, it’s likely that those working in some domains will decide that non-relational databases better fit their needs. That’s progress in our field. It’s fun to watch.

Say it with me: post-relational databases, post-relational storage, post-relational thinking, or simply, post-relational.

Tags:

Blame the compiler

Remember when you first started programming? Those early days when you’d take some code out of a book or article, type it out, and then try to make it print silly things or draw funny pictures?

The thing I remember about those days was the temptation to blame the compiler for all the ills of my code. Something doesn’t work right and you can’t figure out why? Blame the compiler! Of course, this was never right. The compiler is very rarely incorrect.

My goal today is to bring back the joy of blaming the compiler. Of course, Ruby doesn’t have a compiler (yet!), so we have to play tricks. But that’s part of the fun!

Let’s blame the compiler.

See, all you have to do is extend BlameTheCompiler. And then you’ll find yourself with one chance in every three executions to say “Hmm, I’m sure I defined that method. Something must be wrong with Ruby.” Just like those early days of programming, you’re half right. The other half is that you’ve got a little prankster running in your application.

It’s a fun parlour trick. I would not, however, recommend sending code including BlameTheCompiler in as a bug report to the JRuby or Rubinius folks. They wouldn’t find it as funny as you or I.

Tags:

I promised you the details on how we built Tag Better, so here we go. This is what I used to build the back-end bits. You’ll have to pester Chris or Alex to get the front-end details.

Sinatra

Technically, it’s a Rails Rumble. Read between the lines of the rules and you’ll see it’s really a Rack Rumble. And so I went with my favorite for prototyping, Sinatra.

Happily, Sinatra had my back the whole time. I never came across anything that stumped me. Further, I didn’t pay any taxes for ceremony I don’t need.

Verdict: perfect tool for the job.

Passenger

I hadn’t used Passenger much before this weekend. I’m pretty happy spooling up app processes in a terminal and watching the logs scroll past. localhost:3000 is my friend.

However, I’m an outlier in this regard. My teammates aren’t as interested in lower-level bits as I am, so I figured that using Passenger is the best bet to help them get the app up and running locally.

The benefit that I didn’t realize we’d get from this is running the same stack locally as on the production server. Besides some virtual host wrangling that Passenger Pane saved me from locally, getting the app up and running was painless.

Verdict: I am quite likely to keep tolerate Apache for that Passenger goodness, especially when I am the operations guy.

Sprinkle + passenger_stack

The moment that I realized we’d have to set up our own server instance was one of brief, abject terror. I knew this could easily expand to fill a lot more of my time than I wanted. Luckily, I was wrong.

Ben Schwartz’s passenger_stack helped me get our Linode slice up far faster than I would have been able to by hand. I cloned his repo, tweaked it to our needs (disabled MySQL, eventually added a CouchDB recipe) and ran it on our server. Several minutes later, we had a working server. Pretty awesome.

passenger_stack uses Sprinkle, which isn’t getting as much play in the server configuration space as Puppet and Chef. Sprinkle does seem really well suited to standing up apps on a few servers. We might want to step up to something heftier once we had more servers, but Sprinkle and passenger_stack are simple to understand and don’t require any supporting infrastructure to use.

Verdict: Not too primitive, not too involved; just right.

CouchDB

When I’m building any app that relies on an API as its primary data source, caching API response data is forefront on my mind. Serving the data locally, rather than making a request every time, means the app feels more responsive. An added benefit is not upsetting the upstream data provider.

I’ve built apps like this that use MySQL as a cache and it just never felt right. I’ve been tinkering with CouchDB and Tokyo Cabinet/Tyrant lately. I decided to go with CouchDB for this one because of the excellent CouchDBX, which makes it easier for those who don’t even know what Erlang is to use CouchDB.

CouchDB ended up working pretty well. While we haven’t really leaned into it, it didn’t present any challenges while I was developing. Using CouchRest with Sinatra worked just fine.

Verdict: It just worked, which is exactly what I needed.

Skipping traditional TDD

OK, so maybe only Jared Diamond would consider this a technology. But skipping the writing of tests to drive my design was pretty helpful. Consider Kent Beck’s flight metaphor. Doing a Rails Rumble is just like the taxi-ing phase. Or a minimum valuable product. Either way, you want to make a small investment towards validating an idea.

Notice I said traditional TDD. To tell the truth, I did write a sniff test script after I had the basic app working. But it wasn’t an xUnit-style test. It’s just a shell script that bangs on the app with fixed parameters. I do have to manually inspect it to make sure nothing is blowing up. What I’m really automating here is the pain of typing out Curl commands.

Verdict: worked great for the original purposes, but I’ll probably add a proper test suite as one of the first post-contest enhancements


So that’s what I think helped make our project go off pretty well. Really, what they did was help me get stuff done and then get out of the way. Isn’t that the best kind of tool?

Tags: , , , ,

« Older entries