Posts

Showing posts from 2007

Mocking Backticks and Other Kernel Methods

There's a bunch of places in our build where we need to execute a system command (such as running sqlplus) but often times we've found that the command fails and our build happily churns away. It's pretty easy to check the result of system command with $?.success? but we have to remember to do that everywhere... So that means it's time to extract a method. Here's what Kurtis and I came up with: module DatabaseHelper def self.command_runner(command) output = `#{command}` puts output fail unless $?.success? fail if output.include? "ERROR" output end end So you pass in a command as a string and the command runner: runs the command prints out the output fails if the return code is bad fails if the output includes "ERROR" (useful when running database imports with sqlplus) and returns the output just to be a good citizen So that's cool but when I started to write the module I thought "Hey, I can test this." Which is...

Employee Appreciation

As a consultant, I spend a lot of time at big companies and big companies generally have a morale problem. Bureaucracy, cubicles, and lax management will tend to do that. Typically they try to solve this problem by exchanging money for goodwill. A few projects ago I was consulting at one such company where they spent a ton of money having a day of games, burgers, and events during business hours. There was a big ad campaign, lots of promotional tie-ins and give-aways -- a team of people clearly worked on this for weeks (or maybe months). Now add up productivity, food, and sumo-suit rental costs and we are talking some serious money. All worth it in service of employee good will, right? A few days after this spectacle, my team and I decided to walk to lunch. Now the most direct route to our restaurant of choice happened to be through the front door. However, the security guy stopped us when we tried to leave. Employees aren't allowed to enter or leave through the front door....

Metrics for Rails

Everyone thinks they write good code -- it's just part of human nature. You can't do something every day and not secretly suspect that you're good at it. Self-delusion is a powerful thing so you need to use metrics to take a hard look at your code. On my current project, we've just added a daily metrics build (run every day at midnight by CruiseControl.rb ) that takes a look at our code in three ways: Code coverage with Rcov Cyclomatic complexity with Saikuro And um..., Flogging with Flog Rcov is a code coverage tool that can be used with Rails Rcov to add a bunch of rake tasks to your build so you can figure out which lines of code are run by your tests... and which are not. Saikuro computes cyclomatic complexity which "measures the number of linearly independent paths through a program's source code." Methods with more paths are harder to understand/debug/modify. And Flog is cyclomatic complexity with an attitude. It scores ruby methods with an ...

Why 50% Test Coverage Seems More Painfull Than No Test Coverage

Recently I was on a project where a bunch of code had been written before we arrived. It was quite a struggle to get the application under test. After a number of months the team hit 50% and then we just stayed there. We had a hard time getting client developer buy-in on the push upward from 50%. I didn't really understand this attitude at first, but after talking with the devs, I realized that the tests were mostly a nuisance for them. They saw it like this: "If I have to gut a few pages, as part of a changing requirement, now I also have to spend a day fixing the stupid tests. And the tests never really catch any bugs, so what was the point? All the tests are doing is slowing me down." Since the coverage was low and many of the test writers were new to unit tests we didn't really have a lot of protection from bugs. But we also had a sizable suite to maintain. They were feeling all the pain of keeping a test suite running but seeing none of the benefits. ...

Renting American Cars

Image
As a traveling consultant I've developed a pretty poor opinion of American cars. Sliding doors that won't close, unfathomable glove boxes, ugly/boring interiors, boring/ugly exteriors, crazy placements for the radio/ac/heating/trunk release buttons, plastic doors with tails of extra material hanging off poorly drilled holes... The other day I was sitting in a Chrysler 300 talking with one of our tech leads about how he really wishes the rental company hadn't upgraded him and would've much preferred a Hyundai Elantra -- a car that costs half as much as the 300. It's a bit depressing.

Writing Your Own Custom Log Parser

I spent the last week writing a log parser of all things. The web site I'm currently working on is the sign-up page for a large company so they are very concerned about how far the average joe gets into the process before they give up. If everybody bails on the address page, then perhaps it's too complicated or unresponsive or... something. Up till now we've been redesigning pages based on some data and a lot of guesswork so we thought it might be about time to get some serious data on every session every day. Now the first thing you learn about parsing rails logs is that they are designed to be human readable but not so much computer parsable. An Apache request is one line. A Rails request log has lots more info, but is multi-line. And since we run a lot of Mongrel instances at once, all these requests are interleaved, so sorting them out is an intense computation (we actually ran out of memory a few times before we did some optimization). Our first pass was mostly ...

RSpec on Rails: Models

In my last post I talked about using RSpec without Rails, but since just about all my Ruby programming involves Rails, I should probably get into how to specify Rails code. RSpec on Rails: Models So if you're new to RSpec and you want to get started quickly, head on over to rspec.rubyforge.org , get RSpec, Spec::Rails and then, after you've created a new Rails project and rspec-ed it (all detailed on the website) you can run: ruby script/generate rspec_scaffold person name:string phone_number:integer cash:decimal Which will get you a bunch of stuff to play with. Of you'll need to set up your database.yml and run rake db:migrate if you want thing to work. Fire up your favorite IDE and find the person_spec.rb and you should see something like: require File.dirname(__FILE__) + '/../spec_helper' describe Person do before(:each) do @person = Person.new end it "should be valid" do @person.should be_valid end end Not the world's mos...

RSpec without Rails

I'm going to try and turn my recent presentation on RSpec into a series of blog posts -- This being the first. Before I get on with it I would like to thank the Houston Ruby and Rails Users Group for having me. They asked some pretty insightful questions and were generally a great audience. I'd also like to thank ThoughtWorks for paying for my flight, rental car, and lost billable hours so I could do this presentation. RSpec without Rails So in order to show you how RSpec works, I'm going to start with specifying a class that deals with string case like so: require File.dirname(__FILE__) + '/../spec_helper' require 'string_caser' describe StringCaser do it "should upcase a string" do caser = StringCaser.new("A String") caser.upcase.should == "A STRING" end end After requiring a spec_helper and the file I intend to spec, I set up a 'describe' block. Inside the block there is a single spec (or example) which is als...

RSpec Resources

Later this evening I'm giving a talk on RSpec at the Houston Ruby and Rails Group. In case somebody misses a link, I'm posting them here: RSpec's homepage: rspec.rubyforge.org RSpec Users Mailing list: rubyforge.org/mailman/listinfo/rspec-users David Chelimsky's Blog: blog.davidchelimsky.net If you install RSpec as a plugin to your Rails project, then look inside: vendor/plugin/rspec/examples for some nice spec examples Once you've got RSpec and RSpec on Rails installed in your project, running: ruby script/generate rspec_scaffold person name:string phone_number:integer cash:decimal from the base of your project will get you a bunch of generated specs to look at and play with.

I'm Presenting on RSpec in Houston

I've been invited to give a presentation on RSpec at the Houston Area Ruby and Rails User Group on Monday August 6th -- and I'm pretty excited to do it. It'll be a nice opportunity to organize my thoughts and lessons learned after using RSpec on my last two projects. I'll be talking about the why and the how of RSpec (focusing mostly on the how), specifically as it applies to testing Rails apps. Watch this space for the blogization of this presentation.

Caching Dynamically Modified Objects and the Trouble it Causes

So I told you, in a previous post , about how our application has two parts: the live site and the cms. And that we want objects of the same class to behave differently in the two applications (only 'live' status objects should show up on the live site), which is not so hard in Ruby. But a few days later and after some conversations with our architect about how our caching works we realized that we had a huge bug. We use memcached and cache-fu to cache our objects and we share that cache between the cms and the live site for the simple reason that we want an update to the object in cms to blow away the cache for the live site (otherwise the live site would never see the change as it would constantly be referencing the old cached version). But, as you may have already guessed, if the live site gets an object cached from the cms then all sorts of 'draft' stuff will show up on the public site because an object built in the cms will not have the extra special dynamica...

Big Weekend for Nerds

Image
Lots of chatter around ThoughtWorks about the iPhone but, for me, this weekend was all about the Weird Al concert. I got your alpha geek right here, buddy: Great performance -- More costume changes than a Vegas show. And more Star Wars parodies too.

Why does modifying my classes dynamically only work once in Rails?

(Or the downside of class caching) This is a gotcha in Rails where your custom plugin or other dynamic change of a class only seems to work once. First, a little background: Recently we had a problem where we wanted an object to behave differently in two different instances of Rails. Ya see, we have models that are shared by two separately running rails instances. One is a cms (content management system) where all objects (let's say they are of class Thing) should show up. The other is the live site that should only show 'things' that have been designated 'live' (as opposed to, say, 'draft'). Now changing the search to filter out non-live 'things' was easy, but since you can call thing_instance.related_things and get back related objects of type Thing, now we have a problem. In the live site I want a call to 'related_things' to only bring back 'live' objects. But in the cms I want the same call to 'related_things' to bri...

Fixture Migrations in Rails

(This is the third of three posts on Rails fixtures) Awhile back Josh Cronemeyer approached me with an idea to migrate fixtures in Rails. The problem we were trying to solve is when your database changes you need to edit all the fixture files to reflect the change – which usually doesn't happen and then things break/get weird. We spent a few hours hashing out the basic plan (load all the fixtures into the db, migrate, then write the db out to the fixture files) and writing some code. Then he went off, tested it, and made it work with (very) occasional input from me. He's written up a nice post on the topic called How to Migrate Fixtures in Rails and has posted the code at Google Code . Go check it out if you hate migrating fixtures by hand.

What are Rails Fixtures Good for Anyway?

(This is the second of three posts on Rails fixtures) I like using fixtures for setting up a development environment. Applications need data in the db to function so what most teams do is pass around a database, or two, or five. A new person joins the project and he/she gets a dump from one of the devs, imports it and goes to work. What happens when you screw up your db by: Running a bad migration Importing a crap load of data for a task (I remember once filling up a db with all movies playing in North America) but later you don't need it. Doing something dumb. (my personal favorite) Well, you need to get somebody else's db. Which maybe in a bad state and it definitely doesn't have the same data you're used to because they've been changing it a lot. But if you have a bunch of fixtures checked in to source control, you can always go back to a base state. Anytime something is acting wacky and you think it might be a data problem (which happens more and more as th...

Why I Hate Using Rails Fixtures in Tests/Specs

(This is the first of three posts on Rails fixtures) So you have a Person object that has a many to many relationship with Roles and Movies (maybe this is site where people track their favorite movies). So to test it you need to have the following files: people.yml roles.yml movies.yml and the join tables: people_roles.yml movies_people.yml If you want to test that only people of a certain role can edit another person's favorite movie list, then your test is spread out amongst 7 files (don't forget the test file and the actual class file). Maddening enough when you're writing it, but super crazy insane to debug when the test breaks. More than likely a developer will delete/comment out the the test when it breaks, or they will change it so passes but breaks functionality. Long tests that repeat themselves look bad, from a DRY (don't repeat yourself) point of view but consider this: A fixture that is useful for 10 tests tells you nothing about any one test. Many time...

Public Static Final for Ruby

When I first got into Ruby awhile back I found that I wanted to do something like I used to in Java: public static final String BLUE = “blue”; But darned if I could get the internet to tell me how, so here I am giving back to the community: in solar_constants.rb: module SolarConstants MASS_OF_EARTH = 5.98e24 end in some other file: require 'solar_constants' puts SolarConstants::MASS_OF_EARTH or you can: require 'solar_constants' class Gravity include SolarConstants def print_mass_of_earth puts MASS_OF_EARTH end end This being Ruby you can, of course, redefine a constant. But you will get a stern warning.

EVDO Card on a Dell D620 Running Linux

One of the things that kept me from installing Linux on my laptop was concern about support for peripherals such as printers, digital cameras, USB devices in general, and my ThoughtWorks-provided EVDO card. The cool thing with Fiesty Fawn is that all except the EVDO card worked out of the box (I should say I had some trouble with my wireless on Edgy Eft). And the EVDO card only took about 5 minutes to get working after Peter Ryan pointed me to this article: Get broadband wireless with Verizon EVDO and Linux It's a few command line scripts to run and currently I haven't figured out how to turn it off or configure image detail (like you can with Verizon's software), but it works.

The Last Day of Rails Conf 2007

A light day for me as a 4 hour flight + 2 hour time change + wanting to see my wife for a few hours this weekend means I left early. Before I get started I wanted to say a few words about Portland: It's a great city. The train took us from the airport straight to the convention center (and our hotel which was 2 blocks away). Then we found out the train is free in the downtown area. So we had super easy access to bars/food/good times. Also the city, while being big enough to support an ecosystem of coolness is small enough to avoid being overwhelming. Keynote – The Rails Way with Jamis Buck and Michael Koziarski: General format of this talk was here's a submission we got for inclusion into Rails core and here is what's wrong with it. Oddly enough they called the people out by name – the ones who had the bad code. Not sure how I'd feel about being outed like that. [Correction: Koz informs me that people had submitted their code to The Rails Way (not core) and were...

Thoughts on the Second Day of Rails Conf 2007

Keynote (AKA paid sponsor time) – Cyndi Mitchell ( ThoughtWorks ) and Tim Bray (Sun): Cyndi seemed a bit nervous and well she should be – this is ThoughtWorks big play to mold the face of the Ruby/Rails world by announcing RubyWorks . RubyWorks is a “free, open source LAMP production stack is for RedHat Enterprise Edition and CentOS , and will allow users to quickly put Rails applications on production servers.” Pull it down, drop in yer Rails app, and you gots a server. It's all free, but if maybe you'd like some support we could perhaps sell you some. And we'll support JRuby . Pretty big move for us as a company. So why would we expose ourselves to this risk? Other than the tons of money we stand to make, ThoughtWorks feels like the Java/.NET world is all wrapped up with horrible bloatware and bad management practices and while we're still interested in fighting for change in those areas we feel think there's an opportunity to make a real impact in a w...

First Day of Rails Conf 2007

Finished the first day of Rails Conf and here are my impressions: DHH's keynote: Lets celebrate what we have. Blah blah blah. Rails has come a long way. Yadda yadda yadda. Here's a sneak preview of what ActiveResource is going to be like in Rails 2.0. Ooooh, Aaaah. Actually the ActiveResource stuff was pretty cool. With a little bit of setup you can have one controller method serve up xml and text and html and all sorts of stuff. All RESTful style of course. And the debugger will be back (broken when someone fixed a bug in Ruby 1.85) and it will be a real debugger. When will 2.0 be out? He didn't say. Go use edge if you dare. Bob Martin's Clean Code Presentation: On the one hand, this is a lot of stuff I've heard before (I hung around Object Mentor at the start of my career), but Uncle Bob is such a good speaker he got me all fired up again about TDD, Red Green Refactor, and incremental steps. There was this point where a slide was clearly missing from th...

Beware Tomcat5.5 in Feisty Fawn

I moved to the newest version of Ubuntu over the weekend: Feisty Fawn. I was having troubles getting my wireless working (Intel PRO/Wireless 3945) and I had heard it works in Feisty. The upgrade, um, took out my system. Yep. Everything was chugging along just fine until it tried to upgrade Tomcat and then I got a cryptic error message saying the update had failed and I should email them. No real indication of what to do next. So I tried to get the upgrade running again, but I'm not savvy enough with the Linux. Tried to restart the machine... Big mistake. Not so much with the booting. So I had to wipe that partition and reinstall. I didn't lose anything except time. Then today when I was setting up my machine I couldn't get Tomcat5.5 to work (we use SOLR which uses Tomcat behind the scenes for fast searching). Lost more time trying to figure out what was wrong. Finally I thought maybe Aptitude's version was bad, so I removed it and got Tomcat straight from Apa...

Secret Origin of the ‘Super Ultra Critical Showstopper’ Bug

When you first start a project and you set up bug tracking software there tends to be 3 levels of bugs: Low, Medium, and High. After awhile you might notice there are now ‘critical’ bugs. Come back a little while later and there’ll be a ‘showstopper’ or ‘blocker’ bug level. And the funny thing is, most of the bugs will be logged at the highest levels. Literally 50% of bugs are given such a status as to make you think the app is in shambles. Except that when you actually open up qny of them to see what could possibly be so horrible, you find things like: missing fields, pages that should be pop-ups, and misspelled text. How is it that these things are given the highest level of importance? Today, while I was working on a super ultra critical showstopper bug, I had some time to reflect on this phenomena. The bug was this: One of our models was missing a field. And the business wanted this field to be entered before the user could perform some task. Now, I should ...

Chicago in Mid April

Image
Snow turned to freezing rain which turned to rain and then, just to mess with me and my 30 minute walk, tiny hail. The hail hurt my face. That'll teach me to brag about my commute.

Stubbing/Mocking a Partial Within a Partial with RSpec

So in a previous post I complained about not being able to mock/stub a partial from within a partial, but with Peter Ryan and Mike Ward's help we got it all figured out. Normally in your test(spec) you call a partial like this: render :partial => 'partial_name', locals => {:page_variable => mock_page_variable } But if you want to intercept all or some calls to render with partial, them you can't do that. But what you can do is call a partial like so: render '_partial_name' If you need some locals you can stub them out like so: @controller.template.stub!(:page_variable). and_return(mock_page_variable) render '_partial_name' So if I wanted to stub out all calls to render, and assert that the string "Blargh" appears on the page, it would look a little something like this: @controller.template.stub!(:render) @controller.template.stub!(:page_variable). and_return(mock_page_variable) render '_partial_n...

My Commute

Image
Working in downtown Chicago has its advantages -- everyday includes a scenic walk along the Chicago River: And after a hard day of delivering business value, who doesn't enjoy a movie and a nice drink?

Windows vs OSX vs Ubuntu for Ruby/Rails Development

When I first started working with Rails, I had a windows laptop and so that’s where I worked. Later I got on two different Rails projects that used OSX (on Mac minis). Now I’m using Kubuntu . I thought I’d take a minute to compare them all. I’m not going to mince words here -- try to avoid developing in Windows if at all possible for these reasons: Tests will run very slow (by a factor of 10 or more). The mysql drivers are not so good (When I developed in windows, I noticed I kept losing my connection to the database during operations that took more than a second or two and I couldn ’t get any of the replacement drivers to work). A fair amount of the plugins will be much harder to install (we are using the Raspell gem for “did you mean” functionality which needs aspell and the windows dudes still haven’t figured out how to install it. On Ubuntu , it was a simple “aptitude install”). Help online is usually not geared towards the Rails on Windows developer. If yo...

Using OpenStruct to Enhance Your Mocks

So I use RSpec's built in mocking framework for my mocking/stubbing and it works quite well. I sent up a mock like so: mock_active_record_instance = mock("give it a name here, but probably a better one than this") and put some expectations on it like so: mock_active_record_instance.should_receive(:id).and_return(1) but some calls to the mock I don't care about so I can stub them out like so: mock_active_record_instance.stub!(:name). and_return("Arthur, King of the Britons") If I don't need it to return anything I can leave off the and_return and it will return nil. But it's tedious to do that. Lately I tend to use OpenStructs as my mocks like so: mock_active_record_instance = OpenStruct.new mock_active_record_instance.should_receive(:id).and_return(1) Now here's what's cool about that: My spec(test) will fail if the expectation of a call to id isn't met, but any other calls will be ignored (and nil returned). If I had made mock_a...

Rails partials should be explicitly called with locals

Since Rails partials can see all the @variables of their parent view it’s pretty common to see partials with @’s all over the place. But the cool thing about partials is reusing them in other views and if you do you have to remember to populate all the stuff it needs and name everything the way it wants. Bah, I say. More and more I find myself explicitly calling partials with locals even if seems a bit redundant: 'content/poll', :locals => {:poll => @poll}) %> It goes along with this "partials are like methods" analogy I’ve been thinking about lately. And in big complicated pages with lots ‘o partials everything seems more clear. What do you think?

Mocking/Stubbing partials and helper methods in RSpec view specs

In my previous post I whined about not knowing how to mock/stub partials and helper methods in RSpec view specs. Now I have the answer and I’d like to thank the RSpec users mailing list and David Chelimsky for taking my phone call. In short, it’s all about @controller.template @controller.template.stub!(:a_helper_method).and_return(true) Stubs out the appropriately named a_helper_method and returns true. You can mock it out also like so: @controller.template.should_receive(:a_helper_method). at_least(:once).and_return(true) Which is like the stub except that it checks to see that a_helper_method was called at least once For partials you do this: @controller.template.should_receive(:render). with(:partial => 'form', :locals => {:cookie => mock_cookie}) Which checks to make sure the partial _form.rhtml is rendered and that the view attempted to pass mock_cookie in as a local. Since I didn’t specify a return it will return nil and I don’t have to worry about what’s...

What I want from view specs

I got an email today from a friend asking me about specifying views in RSpec in which he admitted he hadn’t done it much and first reaction was “I know what you mean!” Because it’s hard to spec views when you’re not hitting the database. You have to mock or stub out so many calls to your object just to get at the one or two lines you want to spec. And then I realized why I hate specifying views so much: It’s exactly like specifying a huge method. There’s all this stuff going on and you only care about one little bit and so you end up with 10 lines of mocking/stubbing to get to 3 lines of what you really want to say. Now with a ginormous method I have the option of pulling out little pieces of functionality into smaller methods and going straight at them. Then I can stub out those smaller methods when I’m specifying the big one. I can do this a little by creating a bunch of partials and specifying them individually, but when I want to spec the parent of all those partials I need...

Wrapping a Context in a Context (in RSpec)

A few days ago I blogged about solving a sticky problem by overwriting the “new” method on an ActiveRecord object inside a test (spec). Something I should have mentioned is that this is dangerous because if another spec (test) tries to call new and gets executed after the dangerous spec/test is run, then of course it won’t have the original new method. And it’s a very hard error to track down unless you know it’s been redefined. The solution to this, should you need to do it (and you probably won’t – any good mocking framework will probably do what you want), is to wrap a context around all the contexts that need it and use context_setup like this: context 'When the situation demands it' do context_setup do Class SomeObject def some_method_to_overwrite #do whatever I want -- Bwaa ha ha! end end end context 'Some context' do #specs go here end context 'Some other context' do #more specs go here end end After it ...

Rcov/RSpec problem solved in RSpec 0.8.2

I loves me some RSpec, but I’ve had this consistent problem on my last two projects when RSpec and Rcov are run together: Sometimes you get Seg Faults. In a previous post I talked about my solution to this (redefining the new method on ActiveRecord objects), but it was a hacky solution and I’m glad to say that it’s out of the code base as of today. On a hunch this weekend I installed RSpec 0.8.2 (we had been using 0.7.5.1), took out my super-fun hacktacular solution from a spec and it ran fine. But why? Looking through RSpec’s list of bugs fixed I didn’t see any reference to the bug I logged a few months ago (I didn’t really expect too – they were never able to reproduce it) but I do have any idea. David Chelimsky (lead dev of RSpec) had been telling me for awhile about how he was going to change RSpec to stop using method_missing on object because when Rails takes it for its own purposes, then RSpec has to some hacky things to steal it back (David wrote about it in ...

Lemme solve all your problems

Persistent, baffling problem? Windows: restart computer Linux: change file permissions I need to Tattoo this on the back of my hand so I can see it while I type. Long day.

Battle of the method_missings

So if you’ve heard about Ruby, you’ve probably heard about method_missing (short summary: if an object receives a message it doesn’t understand it calls method_missing which you can overwrite. This allows Rails ActiveRecord to handle User.find_by_email_and_name_and_phone_number on the fly -- it parses the message and gives you the method you want dynamically). But when too many things try to use it at once you get some interesting problems. At some point RSpec enabled calling object_instance.should_include('thing') by using method_missing on Object to catch any message that started with should_. So, in the previous example, RSpec would look for a method called include? on the object_instance, pass 'thing' into that, and tell you about it if it failed. Which is pretty cool because instead of saying: assert_equal ['a', 'b', 'c'], object_instance.some_method you could say: object_instance.should_eql ['a', 'b', 'c'] w...

FoxyProxy is bad news

At work we have to go through a proxy to get to the outside world. So every time I take my laptop home I need to switch the proxy setting on my browser. Lame. Surely there is some sort of Firefox plugin to help me with this tedious task. And there is. But Foxyproxy isn't it. It's crazy heavyweight and unpredictable. The heavyweight part is that you can define different proxy settings and each of those settings can have white and black lists (with wildcard or regex matching) that decide whether or not to use a proxy. Or you can mix and match proxies for different sites. All that I could live with, but I just spent a few hours tracking down a bug that didn't exist because of Foxyproxy's weirdness. The feature I was working on involved calling out to an outside system. But the browser just spun and spun when I tried it. After a LOT of time spent talking to people about the right configuration for this 3rd party system I guessed that just possibly this was a prox...

ActionMailer tips

My latest story card is all about getting our app to send email so I’ve had to delve into ActionMailer. It’s a cool way to send emails without tons of code but there are some things that are a little bit wacky. Let us say that you’ve got a cookie website and you want people to be able to send emails of their favorite recipes to each other. “My that’s a handsome cookie” they might say and “Oh look, an email button that lets me send this recipe to a friend. This site has met my needs exactly.” In order to get such a thing to happen you would create a RecipeMailer model that extended ActionMailer kinda like this: class RecipeMailer < ActionMailer::Base def recipe_email(email_params) @from = email_params[:from] @recipients = email_params[:recipients] @subject = email_params[:subject] @sent_on = email_params[:sent_on] @body[:recipe] = email_params[:recipe] end end In your controller you’d call: RecipeMailer.deliver_recipe_email(email_params) And some good old method_missin...

The stack trace that doesn’t mean anything

We’re using an open source java app to help with searching on my current project and when I start it up (through cygwin – must… stop… developing… in… windows…) it throws up a bunch of stack traces. The first time I saw this I thought “holy crap, I must have configured it wrong.” And I was right. But then I configured it correctly and I was still getting a few stack traces on startup. I spent an hour or so trying to fix the problem before I remembered that lots of times a Java app will thow some errors at ya just for fun and I started up the rails app, navigated to the search, and it worked fine. Nice. So I just learned to ignore those stack traces. Can you see where this is going? Yep, later the search stopped working in a spectacular way that took down the whole app. Except I wasn’t sure it was the search breaking it. And I lost a bunch of time because I was ignoring the errors that were telling me something was wrong. They were different errors than the usual...

Rails fixtures on Linux and Windows

At my current gig I develop on Windows while the rest of the team is working on Linux (but not for long, I just got PartitionMagic and I’m going to dual-boot). This has caused several problems and one of the most vexing is that the Linux dudes can check in fixtures that blow up on my Windows box. Every time it happens I take a look at the offending fixture and it isn’t putting something into a column that has been declared ‘not null.’ So I fix it by adding in some data, but why the hell isn’t it blowing up on their machines (or cruise control, which is on a Linux box)? My colleague Ricky Lui figured it out today. Allow me to quote from his email: On our Linux machines, MySQL is installed with no default sql_mode. That means if there's a certain column that's supposedly NOT NULL, your unit tests can still pass even without setting that column (e.g. through test fixtures). For MySQL installation on Windows, the default sql_mode is set, so that same unit test that pass...

You want fries with that?

I’ve got some bad new for ya. I know you’ve been reading this blog picturing me as some handsome muscled young stud -- but I am not. I’m fat and 35 and all muscle has left since I stopped working out about 5 years ago. What happened? Who cares – what I wanna talk about today is how every waiter is trying to kill me. They are! As a traveling consultant I tend to eat out 3 meals a day while I’m on the road. And in order to lose some weight I thought I’d just stop getting side dishes. Hamburger – no fries. Pasta – no garlic bread. Whatever it comes with -- I don’t want it. This is very hard for waitstaff. Here’s a conversation I’ve had about a thousand times: Me - “I’ll have the French dip, but I don’t want any sides” Waiter - (confused pause) Waiter – “You don’t want… Would you like to substitute something else for the fries?” Me – “Nope. Just the French dip is fine.” Waiter – (weirded-out pause) “Um… Okay.” 15 minutes later ...

The perils of keeping your prototype

Oh sure everybody says you should throw out the prototype after you make it, but look at all that yummy code just waiting to be used. Sure you wrote it fast and without tests – but it took a lot of work and it would be silly not to just use it as the base of your real project. Brush it off, clean it up a little, and it’ll be fine. Don’t do it. First of all it’s not fine. Code written without the threat of production tends not to be good. But let’s pretend you did write some nice code (you didn’t but this is pretend time). Now you’ve got huge chunks of untested code floating around that looks like it does stuff but actually is just left over from the prototype. Joe dev comes along and tries to write some functionality and he comes across a bunch of prototype code. It’s really confusing. It’s doing all this stuff. Stuff that doesn’t seem to work like he thought the app was supposed to work… Huh. “Oh well, I guess that’s how they want it done so I better foll...

Theater and Programming

Awhile back I was bored of the suburbs and being a teacher (high school physics for 7 years – no foolin’) so I decided to become an actor. I didn’t quit my job, but I did use my summer vacation to take 3 acting classes at once. It was a crazy good time and I completely recommend it to anyone looking for a change of pace and/or the opportunity to meet lots of pretty girls. Anyway, one of my classes was Improvisation which should really be called game playing for adults. Remember cops and robbers? Well yeah, it was like that. Teacher would get some volunteers and come up with some wacky situation and the 2 or more actors would just play out the scene. You’re a salesman on his way to a big sales call who sits next to a weird guy on the bus. And you, you’re a crazy person who thinks this bus is a submarine. Go. Somewhat scary, but lots of fun. But like cops and robbers the game could stall if people didn’t play fair. “I shot you. No you didn’t” and so on. The num...