Thursday, December 23, 2010

how do you "freeze" individual gems in Rails 3?

Ok, this wasn't documented anywhere, (the best I could find was the Rails 3.0 announcement and the Bundler rationale) so after reading the Rails guide I hacked around with it on my own.

In the old days (Rails 2) you could do something like this:
rake gems:unpack
and it would take the required gems and copy them into vendor/gems.

But Rails 3.0 gets rid of this handy feature in favor of Bundler's approach. Bundler's basic approach assumes that you'll always run bundle install in every deployment environment and that it can go to the internet to get the gems. Neither of these assumptions are valid in my case.

There is one way of doing this:
bundle install --deployment
but that copies everything, rails, ruby, 10,000 gems I've never heard of (well ya, I've heard of 'em, but sheesh) and nicely bloats the target environment. So it seems it is all or nothing.

Anyone else figure this out?

Thursday, December 16, 2010

the single most important unstated rule about BDD...

I've been co-leading a book club at work studying the RSpec Book. One thing that was difficult for me and other people new to Behavior-Driven Development (BDD) is that it often seems like the authors modify code in the BDD part of the cycle instead of waiting until the Test-Driven Development (TDD) part of the cycle.

For example, the first chapters dealing with BDD seem to make a lot of changes in actual code files and only at the end of Chapter 4 do they drop the inscrutable phrase, "now we have our first logical error." I know they mean "our first error that requires going into TDD" (because that's the next chapter), but how does this differ from all the code mucking they've already done? At first glance it looks like you can just skip around writing whatever code you want.

But I've found that the authors of the RSpec Book follow a really important rule that they don't come out and say:
When in the BDD cycle you can define new classes or methods (and even arguments to methods) BUT you are not allowed under any circumstances to change or define the implementation of those classes and methods.
This is super important because it explains why the authors sometimes write code while they're still in the BDD phase-- they aren't skipping around after all!

It makes sense when you think about it because BDD is all about the behavior and interaction between classes (outside), whereas TDD is all about the functionality and implementation of classes (inside). So, of course, in BDD you'd want the flexibility to define an interface on the outside as much as possible before being driven down into TDD.

Many programmers are confused at first about the difference between BDD and TDD and as a consequence, many more have blogged about the philosophical differences (google it!) but I haven't seen any clear rules before. This rule really helps solidify the differences in practical terms so you know exactly when you are in BDD and when you aren't.