Interesting Things
- Shotgun is an automatic reloading version of the rackup command that’s shipped with Rack.
The Golden Gate Ruby Conference is now accepting proposals for talks.
Rails by default stores its session in a browser cookie as an encrypted string. If you want to get the contents of that cookie from within Rails, you can call “session.dbman.send :marshal, session.data“. If you want to get that value from tests, you’ll have to use an integration test, as functional tests mock out too much of the session store.
Ian McFarland and I spoke to Priya Ganapati of Wired this morning about the Palm Pre, webOS and Mojo Application Framework. It was a follow-on interview to Mitch Allen’s Webcast this morning. (Check http://developer.palm.com for the webcast; it will be posted soon.)
Check out the Wired blog post at:
Tim Carroll at Palm Infocenter recently spoke with Chris Sepulveda, our VP of Business Development, to ask some questions about the developer experience working with Palm’s new platform.
The interview (http://www.palminfocenter.com/news/9688/webos-developer-interview-with-pivotal-labs/) provides some early glimpses of the new platform, and puts it into context in the wider mobile space.
We’re looking for more information about Taste or other similar kinds of suggestion engines. What kind of experiences have people had integrating these tools into Rails applications. Are there other useful engines worth looking at?
Direct uploads to Amazon S3 service can be serviced by EC2 servers; however, there might be more direct ways of doings this with S3.
Newer versions of RubyMine have been reported having problems running the gem version of rspec but a solutions has been found. The problem comes from the way gems are specified in RubyMine. You need to add the rspec gem you are using to the Project Structure >> Ruby SDK and Gems.
Using Desert and exception notifier can cause some slow startup times. If you are seeing this problem try moving exception notifier’s sender_address inside your environment’s post-load block.
The scene: Pivotal NYC
Jeff Dean walks up to Dan Podsedly, manager of Pivotal Tracker development.
Jeff: Hey Dan, you asked what features we wanted in Tracker. How about a way to automatically mark all my “Finished” stories as “Delivered”, all at once?
Dan: (with a sly smile) Well, we have an API call for it …
Thus was born my humble capistrano task which marks all your “Finished” stories as “Delivered”. Hook it into your demo deploy task and save yourself some time.
As an added bonus, if you have Paul Dix’s sax-machine gem installed (it’s a SAX object parser that uses nokogiri, which I co-wrote with Aaron Patterson), you’ll even get a brief summary report of the delivered stories in your cap output.
The code is below (you’ll need to generate a Tracker API key). Now go deliver some stories!
#
# To use this task, simply set the following variables:
#
# set :pivotal_tracker_project_id, PROJECT_ID
# set :pivotal_tracker_token, TOKEN
#
# Then, inside the task for your demo platform, add
#
# task :demo do
# ...
# after :deploy, 'pivotal_tracker:deliver_stories'
# end
#
namespace :pivotal_tracker do
desc "deliver your project's 'finished' stories"
task :deliver_stories do
require 'rubygems'
require 'activeresource'
class Story < ActiveResource::Base
self.site = "http://www.pivotaltracker.com/services/v2/projects/:project_id"
end
Story.headers['X-TrackerToken'] = pivotal_tracker_token
puts "* delivering tracker stories ..."
response = Story.put(:deliver_all_finished, :project_id => pivotal_tracker_project_id)
begin
require 'sax-machine'
class Story
include SAXMachine
element :name
element :story_type
element :estimate
element :description
end
class Stories
include SAXMachine
elements :story, :as => :stories, :class => Story
end
doc = Stories.parse(response.body)
puts "* delivered #{doc.stories.length} stories"
doc.stories.each do |story|
puts " - #{story.story_type}: #{story.name} (#{story.estimate} points)"
end
rescue LoadError => e
puts "* stories delivered."
end
end
end
In my last article I ask you to visit Blabs and participate in a simple split test. A few hundred of you were nice enough to humor me and we were able to collect some statistically significant data. It turns out you like pictures of us, and love blink and marquee tags.
To elaborate, I started with a goal of driving traffic to our “Who” page, with the idea that this would be a good proxy for how well we’re getting readers of our blog interested in Pivotal (people are our secret sauce). I then created two new versions of the Blabs page (below), one that added Pivots’ pictures to their posts, and a second that added pictures and a big blinking “click me” button.

Control Page: The Current Blabs Landing Page

Variation 1: The Blabs Landing Page With User Images

Variation 1: The Blabs Landing Page With ‘Click Me’ Link
Web Optimizer requires that each of these pages be at unique URLs, so I added a query parameter to my controller ‘p’ that could be set to 1 to create the first variation and 2 for the second, e.g /blabs?p=2. You may have noticed this if you visited the page and weren’t in the control group. Here’s what the Web Optimizer (WO) summary screen looks like:

I wont get into configuring WO as it’s pretty dang easy. So, without further ado onto the code…
I started with a simple base class to take care of the JS and conditional logic around it (web_optimizer_test.rb). WO requires a specific bit of JS on the control page that does not appear on the variation pages, which web_optimizer_test takes care of for me.
I then created a subclass that contains functionality specific to the two permutations I was testing:
class BlabsSplitTest < WebOptimizerTest
def initialize(id, control, plea=false)
super(id, control)
@plea = plea
end
def show_images?
!control?
end
def shameless_plea?
@plea
end
end
With this done the controller code became pretty simple. I just needed created this object with the test id (created when making the test in WO), and the parameter onfo (e.g ?p=1) from the request:
class BlabsController < ApplicationController
before_filter :setup_ab_test
protected
def setup_ab_test
@profile_image_test = BlabsSplitTest.new('2726898050',
params[:p].nil?, params[:p] == '2')
@profile_image_ab_testing_control_js = @profile_image_test.control_script
@profile_image_ab_testing_tracking_js = @profile_image_test.tracking_script
end
end
The second and third arguments to BlabsSplitTest.new are a bit confusing. The second (control) is true if we request the page with no p param. If p is defined we’re on a variation page. The second argument is necessary because I have two variations, and is true when we’re on the “shameless plea” version of the page (p=2).
Since all the logic for what to do is encapsulated in this object, the blabs template is pretty easy to understand:
<!-- images -->
<% if @profile_image_test.show_images? %>
<%= image_tag(user_img)%>
<% end %>
<!-- sidebar -->
<% if @profile_image_test.shameless_plea? %>
<div class="sidebar-node alarming">
<marquee>Split Test in progress!</marquee>
<blink>
<%= link_to "please click here", '/who' %>
</blink>
</div>
<% end %>
That’s all there is to setting up the test. All that’s left is to track conversions, which we do on the “Who” page, which happens to be served up by the User controller. Here I could’ve used a BlabsSplitTest, but since I apways print out the same JS (and I refactored to BlabsSplitTest) I just use the WebOptimizerTest directly with the same test id:
class UsersController < ApplicationController
before_filter :setup_ab_testing
protected
def setup_ab_testing
@profile_image_test = WebOptimizerTest.new('2726898050')
@profile_image_ab_testing_conversion_js = @profile_image_test.conversion_script
end
end
and include the JS in the corrisponding template:
<%= @profile_image_ab_testing_conversion_js %>
That’s all there is to it. In terms of results, WO provides a running summary of the test and can be turned on/off without a redeploy whixh is very nice. Here’s my final summary:

which indicates we should add blinking marquee tags to all our pages, so stay tuned….
In terms of my opinion having implemented a simple test, I like WO overall and recommend it for simple tests and/or new testers. The reports kept me from having to bust out my stats book, and I didn’t have to keep the data myself, which was a plus and would be great at scale.
That said, WO seems limited in some key ways and I expect to outgrow it rapidly. For example, the Blabs controller and our “Official Blog” controller have a common ancestor, so it should be easy to have a parallel test there with one line of code. I would have loved to do that, however the conversion script uses a global variable to track which test it’s for so — as far as I can tell — you can’t have multiple tests end on the same page (e.g eight tests that all convert when a user registers).
This was fun for me, I hope y’all found it useful as well.
A problem I had as a git newbie, and one I’ve seen others struggle with, is the problem of how to conveniently stage the deletion of files which are already deleted from disk, but aren’t yet reflected in the index? That is, without ‘git rm’ing them one at a time or using some other hack (e.g. ‘git ls-files –deleted’) to do so.
The answer is ‘git add’
Specifically with the following options:
-u, --update
Update only files that git already knows about, staging modified content
for commit and marking deleted files for removal.
-A, --all
Update files that git already knows about (same as --update) and add all
untracked files that are not ignored by .gitignore mechanism.
Also of note: the very handy –patch options, which allows you to selective stage change changes on a change hunk or whole-file basis. –interactive is a more involved version of this. It’s a great way to untangle disparate changes for commit. More here.
-p, --patch
Add modified contents in the working tree interactively to the index.
Pair programming is the subject of endless discussion and debate. How often should we pair — 25%, 50%, 75%, or even 100% of our development day? Should we pair on remedial tasks as well as feature development? What about infrastructure work or research? Is pair programming valuable at all, or should we kick that hippie kumbaya crap to the curb, put on our headphones, and get some real work done?
Personally, I’m somewhere in the 95%-pairing range. Simple stories and bug fixes have a way of becoming complicated (or implemented sloppily) when soloing. Infrastructure is a notoriously siloed realm and spreading that knowledge around can only help everyone. Investigating production database issues, estimating stories, writing CSS, chopping up images using Fireworks — share the love!
So what is the last 5% for? Futzing.
I’m “futzing around” when I’m not doing anything important, maybe even wasting time, at least from a pure productivity perspective. Interestingly, while I’m not implementing features or fixing bugs, I’m expanding my mind. I’m learning in a way that is not conducive to pair programming or any interaction at all with other people: I’m exercising my personal way of learning that that is unique to me. Here’s an example:
On my current project, we’re using very advanced, powerful CSS selectors that blow my mind. While I understand what we are implementing and can see the immediate affect upon the application, it is impossible for me to grok the enormity of these techniques even though my pair is a master and great teacher. I’m learning, but not necessarily understanding. Collectively we are not in a teaching mode, we’re in a cranking-out-awesome-stuff mode. Now, I am not suggesting that we are hacking or moving too fast to learn — on the contrary, we are both learning much, and I often ask my pair to slow down and explain what the hell .div:first-child:not(.row) + .row is doing. Our joint mission, though, is to get stuff done, not to explore every CSS pseudo selector. I’ll futz around with that later.
When I’m learning something new, especially when it’s complicated, I eventually need to futz with it by myself, with nobody looking over my shoulder. I need to flip all of the switches, break it, fix it, break it again the same way, fix it, throw in a little salt and pepper and try again. I need to try every parameter individually, then try to combine them. I need to hack and not feel bad about it. I need to do stupid stuff that could never possibly work because, even if I’m told such, I need to try it myself. Finally, I need to do this for 30 minutes until the “ah ha!” moment hits me and all of the tumblers fall into place in my mind.
Why don’t I do this with a pair? Because I must be in the driver’s seat the entire time with no consideration for pair programming etiquette: talking things through, taking turns, letting my pair try his ideas — no way. I need those brain cycles to figure this stuff out, to make the mental connections that are shorting out. I don’t know what I don’t know, and I need to find out for myself, in my own dumb way, by futzing around and making mistakes. Finally, I need to more than learn: I need to understand. When I’m done, I will use that new understanding during the other 95% of my development time to help my team build the best products we possibly can, and encourage them to futz around a bit on their own, too.
“Need help overriding some of ActiveScaffold’s css properties.”
The general census around the room is that ActiveScaffold has been painful and we should think about replacing it with normal “scaffolding” functionality. Short of that, if anyone has experience with ActiveScaffold, please step forward.
On a clean project, setting up RubyMine 681 (possibly 535 as well?) with RSpec 1.12 only worked when RSpec was installed in the vendor/plugins directory. Others have had luck with RSpec installed only as a gem.
RubyMine 681 file renaming is broken.
Two cool new features in RubyMine 681 are the Gem Manager and Extract Method Refactoring.
Running gem env from a terminal on Mac OS X often has two GEM PATHS: a sudo’ed one and a non-sudo’ed one. It’s helpful to delete the non-sudo’ed one and only install gems using sudo (or geminstaller -s).