Sunday, November 28, 2010

Lowering the barrier to metaprogramming


I've been trying to finish the Io chapter of Seven Languages in Seven Weeks, and I just added indentation to the LispML implementation. At the end of the Io chapter Bruce says
Io’s syntax is remarkably compact. You can learn Io very quickly. Once you understand the core syntax, everything else is learning the library structures. I found that I could work my way into metaprogramming quite quickly, within my first month of using the language. In Ruby, getting to the same point took a little longer. In Java, it took many months to get to the point where I could make any sense of metapro- gramming at all.


He is right on the money! But edit "within my first month" to "within my first week". Also, since there isn't special syntax for metaprogramming you aren't likely to forget how to do it. All you need to understand is how a method call in Io works, and you are ready to metaprogram.

Friday, November 26, 2010

Io Language: the init method


I'm slowly working through Bruce Tate's book "7 Languages in 7 Weeks". It is ambitious and lots of fun. In the Io chapter I struggled and I think it was because Bruce forgot to mention Io's init method. The init method is automatically called anytime a prototype is cloned and it is important becuase if you can't setup each clone, you can't have full fledged instance level behavior. Here is some code I wrote after reading Bruce's intro to Io.

Closet := Object clone do(
closet := list()
stash := method(item,
self closet append(item)
)
peek := method(
self closet foreach(item, item println)
)
)

myCloset := Closet clone
yourCloset := Closet clone
myCloset stash("rollerskates")
yourCloset stash("bowling ball")
"My closet looks like:" println
myCloset peek

"Your closet looks like:" println
yourCloset peek

If you run that code you will see it print out the following:

My closet looks like:
rollerskates
bowling ball
Your closet looks like:
rollerskates
bowling ball

Whoops. My closets aren't behaving like separate instances! What is going on? Well, in prototype if an object receives a message and no slot exists to receive that message, it forwards that message up to its prototype. In this case, the closet slot is on the Closet prototype, so closet is like a class variable. It sounds simple, but it took me awhile to understand what was happening. I had been assuming that a "clone" was an object identical to its prototype, but it isn't identical at all. In fact, initially the closet clones have no state or behavior of their own. It felt like something was missing...

Of course! These clones need to be able to initialize themselves. With an init method each of the clones can have their own closet slot. No more shared state.

Closet := Object clone do(
init := method(
self closet := list()
)

stash := method(item,
self closet append(item)
)

peek := method(
self closet foreach(item, item println)
)
)

Run that the same way we did previously and you get:

My closet looks like:
rollerskates
Your closet looks like:
bowling ball

Which is what I meant originally.

They say learning 1 new language a year will make you a better programmer. Bruce's book can help keep you well ahead of that curve.

Wednesday, June 23, 2010

Testing image generation with Cucumber and Sikuli


Image recognition can be a useful weapon in your testing arsenal. Our current project is a rails app that generates advertisements. We use sikuli's image recognition to detect that the text and images that we expected to be in the advertisement were actually in the ad. To integrate sikuli with our build we simply created a cucumber step that calls sikuli. Let's cut to the chase and see a sample test.

Scenario: Dealer places a Campaign Ad
Given "Bill Murray"'s dealership "Ghostbusters" exists in the system
When I log in as "Bill Murray"
And I book a "Year End" campaign ad
Then the ad proof will look like "ghostbusters_tag.png"
Cool. The magic sikuli step is the one that looks at the ad proof. Here is the step implementation.
Then /^the ad proof will look like "([^\"]*)"$/ do |filename|
feature_dir = File.expand_path(File.dirname(__FILE__) + '/../../features')
sikuli_script_dir = "#{feature_dir}/sikuli"
verification_image = "#{feature_dir}/images/#{filename}"
result = `/Applications/Sikuli-IDE.app/Contents/MacOS/JavaApplicationStub #{sikuli_script_dir}/verify_existance.skl '#{verification_image}'`
result.should match(/hallelujah/)
end
Pretty straightforward. Call sikuli and pass it a sikuli script and the image. The sikuli script returns the word 'hallelujah' if it looks at your app and determines that the verification image exists anywhere on the screen. Ok. Lets drill down into what the sikuli script looks like. Get your Python goggles on...
import sys
image = sys.argv[1]
switchApp("Firefox.app")
type(Key.DOWN, KEY_CMD)
if exists(Pattern(image).similar(0.91)):
print "hallelujah"
else:
print "bugger"
This one is brief, but I'll explain a bit. Sikuli is a cross platform tool for scripting your computer as well as interacting via image recognition. In this script we make sure that firefox is the app in focus. The image we care about is at the bottom of the page so command down tells firefox to go to the bottom of the page. Finally it looks for the image match. The 0.91 number is basically telling sikuli to be damn sure. We print hallelujah if there is a match.

Ok. That is what I am doing, but in practice how does it work? Well, it has actually been pretty trouble free, and it even finds bugs and problems. Amazing! However it isn't perfect. Here is my long list of things that could be improved:
  • Sikuli's documentation on how to run sikuli from the command line is out of date.

  • You have to compile the python down to an skl file if you want to run from the command line. Annoying.

  • Use sikuli IDE's screenshot mechanism. Other screenshot tools cause trouble.

  • Set the similarity number high to prevent false positives. For example at 0.85 similarity, sikuli couldn't tell the difference between the word Ghostbusters and Ohostbusters.

  • Creating the screenshots for tests is tedious

  • My sikuli script is naive, which means if you have multiple firefox windows open it could fail erroneously

  • A popup warning or some always on top window could cause the test to fail erroneously

  • If the browser scales the image your test will fail erroneously
This has been indespensible for our application, because it lets us know if we have broken the integration with InDesign. It also gives us a way to test that our InDesign server is behaving. Image recognition is a bit of an edge case when it comes to testing web applications, but it is an interesting tool for testing and one that is highly adaptable. For images generation applications including charts or custom javascript controls I think image recognition would be the only way to test. It would be super cool to have an image recognition gem because then we would be able to do these kinds of tests without calling out to sikuli.



Just for fun I included this last screenshot. It is sikuli IDE's nifty little image recognition troubleshooting tool. Here I have turned down the similarity number to 0.5 and sikuli is showing 3 matches for my test image of the cucumber on the page. The bright red match is the strongest and the pink and purple are weaker.

Monday, June 21, 2010

Lines of code vs. Lines of test

My last project was a rescue mission. A 20k line rails app with only about 34% line coverage from the tests. No wonder the previous team had failed. 5 months later we made a successful rescue, and were up to about 71% line coverage. Watching those stats go from totally-screwed to mostly-un-screwed felt good. Metric_fu provided all the cool and useful graphs for that project: rcov, flog, reek, etc. One graph that was missing was lines of code vs. lines of test. I was sure that graph would have made a big beautiful X marks the spot, because LOC had steadily gone down and LOT had steadily risen. The moment those lines crossed would have been a great opportunity for toasting the health of the codebase.

Well, good news for those of you looking for excuses to toast your codebase. The brand spanking new Metric_fu 1.4 features a froody new LOC vs LOT graph.
I've been using it on my new project. This codebase is healthy, so no X marks the spot action here, but it is still interesting. From our graph it looks like things started out with 2 lines of test for every line of code, and have been working their way towards 3 lines of test for every line of code. (Our rcov % has stayed about 98% the whole time.) Does that mean that as the codebase increases you have to have an increasing ratio of tests to code? Given a sampling of 2 projects I can't really make any useful generalizations. But what I can do is recommend metric_fu to everyone. Graphs are a great way to start talking about how to improve your codebase and your process, and metric_fu makes it easy to get started. And remember, always use your Vanna White hands when you are exhibiting your graphs to your team mates. If it can make a game-show as lame as Wheel of Fortune successful, then it may work for you.

Thursday, June 17, 2010

Build your views before working on the controller


For complex forms you save time by building your view before you write tests and code for the action in the controller. For example take the following view code:


- form_for :ad_request, @ad_request, :url => ad_request_feature_path do |f|
= f.error_messages :class => 'error'
.form
#publication.form-item.first
- f.fields_for :car_selections do |cs|
= cs.label :headline, "Headline:"
= cs.text_field :headline


Unless you bleed rails you probably can't guess what the params hash posted to the controller will look like. Fortunately for lazybones like me you don't have to guess. Simply create the view, run up your app in dev mode, and post this form. Of course you get an error, but if you look in your app logs you are rewarded with a real life example of your params hash, like this:
{"ad_request"=>{"car_selections_attributes"=>{"0"=>{"headline" => "Mini for $15,000 Driveaway", "id"=>"1"}}}
Great. Guess what you should do with that nugget? That's right! Use it as the starting point of your controller test:


it "should save headline" do
car_selection = Factory.create(:car_selection, :id => 1)
ad = Factory.create(:ad_request, :ad_type => 'retail', :car_selections => [car_selection])
post :feature, {"ad_request"=>{"car_selections_attributes"=>{"0"=>{"headline" => "Mini for $15,000 Driveaway", "id"=>"1"}}}
ad.car_selections[0].headline.should == "Mini for $65,000 Driveeaway"
end


This is one of those things that is almost too pedestrian to even talk about, but it can save you time and pain in the long run, especially for the occasional nasty forms with deeply nested objects.

Wednesday, May 19, 2010

Simple Tabbed Navigation in Rails


Let's say I have a webapp that can be broken into 3 broad categories of activity: Lies, Damn Lies, and Statistics. My webapp has a tab for each of these categories. When I am on the page that tells Lies I want the Lies tab brought to the foreground. When I am creating a new Damn Lie I want the Damn Lies tab highlighted, etc. This is basic webapp stuff. In the rails universe many gems have been written to simplify this, but unless you have complex requirements I call YAGNI! I worked out a simple solution for this and thought I would share.

Diving right into the code let's look at the markup that creates the tabs. I keep it in the toplevel application layout, so it appears on all pages of the application:

<% yield :selected_navigation %>
<div id="container">
<div id="tabs">
<ul>
<li class="<%= selected_navigation(:lies) %>">
<%= link_to "Lies", lies_path %>
</li>
<li class="<%= selected_navigation(:damn_lies) %>">
<%= link_to "Damn Lies", damn_lies_path %>
</li>
<li class="<%= selected_navigation(:statistics) %>">
<%= link_to "statistics", statistics_path %>
</li>
<li class="logout">
<%= link_to "Logout", "/logout" %>
</li>
</ul>
</div>
</div>

First, notice the yield for :selected_navigation. Views in the application implement :selected_navigation and use it to set a variable that maps a page to a particular tab. Here is a snippet from a page that maps to the :damn_lies top navigation element:

<% content_for :selected_navigation do%>
<% @selected_navigation = :damn_lies %>
<% end %>

The final piece of the puzzle is the selected_navigation helper that is being called for each li in the layout. It compares the current page's navigation mapping @selected_navigation to the desired tab. If it finds a match the "current" class is added to the tab. And that gives the user a visual cue as to which tab we are currently on. Here is the code for the helper:

def selected_navigation(element)
element == @selected_nav_element ? "current" : ""
end

This is a lightweight solution. I like it because it doesn't require you to put anything in the controller, or to have some annoying configuration file that maps pages or controllers to tabs. So how do you usually do this?

Wednesday, April 21, 2010

If it's soap, why do I feel so dirty?


I have an son 19 months old. He wears white converse lo-tops, each one smaller than a computer mouse. My other baby is a rails app I've just started working on. It is 8 days old today! This little rails app has reached an important milestone. It is live! Deployed! It's like a toddler taking its first steps.

Me: "The internet is a big place baby!"
It: "Gaaaaaa!"
Me: "I don't quite understand."
It: "Gaaa Gaaaa Ga!"
Me: "One second. I'll take a look at the logs... Oh Yuck! Your diaper is full of XML!"
It: *crying*


Integration. Growing pains. You've been there. My little baby integrates with Adobe Indesign CS4 server. And boy, what a piece of junk it is. If you look closely at the words "Indesign Server" you can see that "Server" has been stuck on with a wad of chewing gum and a roll of tape. Integration is done through a little soap interface that doesn't really understand soap. The ruby gem savon couldn't get a message through. I nearly lost my cool. Just as I was about to get out my blowtorch and a troop of monkey patches I had a brainwave. The API only specifies one command, "runScript". Why do I need a soap library for an API with just one command? I don't! I simply created a template from the sample soap request supplied by their instructional PDF. Then I threw in a bit of string interpolation and presto! Soap without all the horrible boiling chemicals, lye and fat. (BTW, Sorry for the lousy baby metaphor. But not for the XML thing. I really feel the same about poopy diapers as I doo about XML.)

Tuesday, April 20, 2010

Engine Yard vs Heroku: Getting Started


Today we evaluated Rails cloud hosting offerings from Heroku and Engine Yard. Each company claims you will have your app up and running in minutes. I thought I would take a moment to share our experiences with each vendor.

Here is the Heroku narrative.
Signup was simple. Just confirm your email address and you are in. Free rails hosting without a bunch of BS. And it is a good service. You can't beat Heroku for that. Deployment is simple if you run a vanilla application, but you can run into all sorts of problems if you don't. Heroku applications run in a sandbox where your filesystem is readonly (except tmp). We ran into 2 problems. First, we are using bundler. Normally you gitignore your .bundler directory in your application, but because of the heroku readonly filesystem you have to commit your .bundler directory so when heroku runs bundle install there is a environment.rb file already in place. Another gotcha is that we use sass, which compiles to css. You have to check in the compiled css files for the same reason. There is a gem called hassle (hilarious) that has been created to get around this problem. Finally, we got the app up and running on Heroku. I still give heroku high marks becuase of the free service and the possibility of a simple deployment. My Heroku pro tip: If you plan to go Heroku, deploy the moment you create the skeleton rails application and make deployment a nightly step in your CI server. That way when you introduce some dependency that Heroku hates, you know immediately.

Now for the Engine Yard narriative. Signup is again pretty easy with EY, but you have to have a credit card to do anything because creating an app instance costs 11 cents an hour. Move along freeloaders. No free rides at Engine Yard! Deployment is very customizeable, yet simple. Give them the URL to yout git repo and click "deploy". EY pulls your app and does the rest. While using bundler at Heroku was major ass pain, with EY it is a big benefit becuase you don't have to manually specify the gems on your server. Simply install the bundler gem. Then create a file called deploy/before_migrate.rb in your application. In that file you can call "bundle install", and you are all done! The beauty of EY is that you can use a fancy web interface to do nearly everything, or you can drop down to SSH and hack around at the command line. So though it looks harder because there are more levers and knobs, in the end deployment at Engine Yard is easier than Heroku because the environment is alot like your development environment. There are no magic readonly filesystem or special remote rake tasks. If I want to see what's up with the app I can just tail a log file or run script/console. Overall high marks for EY's customizeability, and ease of deployment. My EY pro tip: go look at "chef" the deployment tool that EY uses on github. If your app has any custom tasks that you need to run before it starts up you can specify them there.

What about cost?
Heroku offers a free service, which is a totally awesome resource for the Rails community. Hats off to Heroku for that. On the downside, with Heroku everything is an add on. 20$ a month to send emails, 100$ a month for SSL, 200$ a month for a dedicated DB. That adds up! EY's cheapest option runs about 70$ a month. A dedicated DB system costs 170$ a month, but there aren't lots of add on hidden costs. The big kicker is that with Heroku you pay lots of money to run a single application. With EY you pay lots of money and get a server which means you can run as many applications on that one server as you like. I think you get more bang per buck with EY.

I know. Blah blah blah, what is the verdict? Well, sorry to dissappoint, but as usual, it depends. If you want it to be free Heroku is the only game in town. If your application is very, very simple or doesn't have any of these constraints, Heroku is probably the way to go. But, if you are willing to pay for it you get more bang for your buck with EY.

Both companies have great offerings. I'd say use both of them. The great thing about being in the cloud is that you are paying on a hourly or per cpu cycle basis. Just turn the server on when you need it. If you aren't using it, you don't pay.

Monday, April 12, 2010

Rails for Fashionistas


Today somebody asked me if I would use Rails without plugins or gem extensions. Can you believe it? I looked her up and down and gave her the triple snap. Then I asked her If I looked like the kind of programmer that would let my apps go prancing around the inter-tubes naked? Like, even on a bad day I'm going to dress up my application in a few sexy little plugins, not to mention some tastefully chosen gems. At this point she asked me for advice on which plugins and gems to use. Here was my advice:

Wanna wear something classic? Will_paginate is like the little black dress of plugins. It looks good year after year. Want something a bit more risky? Haml and Sass are hot right now, but they'll both probably go the way of the swatch watch. What's out of date? restful_authentication is like soooo rails 1.x. Another thing is that the big fashion houses are always worth watching. 37 Signals? they are like Versace, Gucci and Prada all rolled into one. DHH, OMG, you brought sexy back. Thoughtbot? Yea, they're another one you can count on for high-end ready-to-wear accessories. Like, when I think about factory_girl's Factory.stub method I go out and by my infant son a new fur coat.

So, like, you can tell our conversation was going well, but can you believe it? Some neanderthal wearing a pager interrupted us. He started talking about Struts and some kind of config file generator plugin for eclipse he was working on. Before we could stop him he emailed us the url of his CVS repository. Then he got paged and had to leave. We both looked at each other and laughed until we cried. I mean, please! Don't talk to me about your Java frameworks. I don't shop at Wal-Mart and I sure as hell won't use J-terd. Hey Ricky Martin, 1995 called and they want their animated gifs back!

That's right sweetheart, Rails is all about the bling! Sure, sometimes late at night while github is down and the home shopping network is the only thing on TV I find myself thinking about something Zed Shaw said. Then I pour out some liquor for _why the lucky stiff. I hit rock bottom and imitate Marilyn Monroe making drunk kissy faces to JFK. Camellllotttt! Where have you gone!?! But then @wycats tweets about the Rails 3 beta and I'm like, "Screw it! Rubys are a programmer's best friend!"

Monday, April 5, 2010

Google Custom Search: Cool but Crippled

Wouldn't it be cool if you could jump over Google's fence, steal their magic 'web searchy thingy' and use it for your own insane schemes? Turns out you can. Some time ago Google created a little happy place called Google Custom Search (GCS) where anybody can have fun pointing that magic thingy at whatever they want.

Cool! Anything I want! Lets make a search engine for programmers! We'll only index useful sites about programming. Here is the algorithm:
  1. Create a set of keywords that encompass all possible useful programming topics.
  2. Use the keywords on sites like delicious to get a set of useful urls.
  3. Create a GCS with all the urls
Implementation of that algorithm found here.

That is foolproof. NOT! Google limits you to searching only 5000 sites with GCS. Poop! But wait you say, 5000 seems like alot. Let's see: a quick first attempt at the above algorithm gave me 65 keywords. 10 pages of delicious search results for each keyword gave me 16,000-ish urls. Yipe! I tried running some searches with just 2000 urls and it was kind of sucky.

GCS Fail.

What's the workaround? The only thing I can think of is that maybe 5000 urls is enough for a decent search on one specific topic. Instead of creating one general programming search I could just create a million specific ones on demand. That makes a plain old Google searches sound easy by comparison. GCS is a nice idea, but they've crippled it so there is no possible way it can compete with the standard Google search unless you are working against an extremely focused collection of websites.

Wednesday, February 24, 2010

Vim vs. RubyMine

RubyMine (RM) is my favorite Ruby IDE. Vim is my editor of choice. Which one is best? I'm going to try to find out. Here are the features I will be judging on.
  1. Quickly find files
  2. Keep recently used files at my fingertips
  3. Autocomplete long variable and method names
  4. Do common VCS commands like diff and revert
  5. Supply a tree view of the project directories
  6. Jump to method definitions
  7. Text search
  8. Run Tests
  9. Debug
  10. Performance
  11. Cost
  12. Learning Curve
On its own Vim can't do many of these things, but thanks to some powerful plugins this will be interesting. You can find my entire .vim directory and my .vimrc on github

Things to note
  • I'm using the rails codebase to illustrate my examples.
  • I'm omitting installation discussion and ask you to refer to github if you need details on how things are configured.
  • My plugins have keymappings that are setup to be reminiscent of RM/IntelliJ
  • vividchalk is simply the best color scheme with desert256 a close second
Quickly find files

In vim I use the fuzzyfinder plugin for this. In RM there is "Go To File" (ctrl-shift-n). Both of these pretty much just work, each one has nuances that skew things in their own favor so I'm calling this one a draw. Here is a screenshot of me finding base.rb in active_record with fuzzyfinder.




Keep recently used files at my fingertips


In vim I use the MRU plugin for this. It shows you a list of most recently used files and lets you quickly jump to one. I map this plugin to ctrl-e. RM has the same functionality. Once again a tie.

Autocomplete long variable and method names


In Vim I use Supertab for this and it is an amazing tool that nearly always offers good completions. By contrast RM ctrl-space often times offers no suggestions. Here is an example. Opening up active_record/base.rb to the respond_to? method in each app, when I begin to type DynamicFinderMatch, "Dyn..." and ctrl-space in RubyMine I get no suggestions. With supertab I get 3 suggestions: Dynamic, DynamicFinderMatch and DynamicScopeMatch. Below are some screenshots of Vim and Rubymine tab completion in action. Viva Supertab!





Do common VCS commands like diff and revert

In Vim I use the vcscommand plugin for this. Mostly I do things like diff my working copy against the repository, revert files to pristine condition or look through the VCS logs. vcscommand does all these well, plus it supports more VCS systems including git, hg, and bzr, but Rubymine really shines because of it's excellent visual diff/merge tool. Winner RM. Here is a screenshot of vcscommand showing base.rb's commit history.



Supply a tree view of the project directories

In Vim I use the NERD tree plugin for this. I find nerd tree to be just as good as the project view in RubyMine, though it is more difficult to use because I can't be bothered to remember all the nifty commands and shortcuts for doing things to the filesystem via the NERD tree. Edge RM.



Take me to method definitions

In Vim I use exuberant ctags for this. This is a standard vim feature, not a plugin. Ctags builds an index of your code that vim can use to navigate files. It works ok for standard ruby, but with lots of metaprogramming (rails anyone?) it really sucks. RM command+click offers much better support for this. Caveat, I think rails.vim helps with this and lets you jump to related files (related controllers and views or models and migrations), but for jump to method and variable definitions RM is king.

Text search

You can do inline grepping in vim with grep.vim, but I usually just grep from the command line. Once again this is an area where RubyMine has the edge. RM's collapsable search results that you can click through are powerful.

Run Tests

You can invoke tests from either one (though I don't have it setup in vim because I just use autospec which constantly runs my tests in the background). Still RM has pretty green bars and I'm a sucker for that. Edge RM.

Debugging

Vim has a Ruby Debugger called vim-ruby-debugger. Doing TDD I rarely find myself in need of a debugger so I haven't played with it. From the description and screenshots it looks as good as the RubyMine offering, so I'll give it the benefit of the doubt here and say tie or even who cares.

Performance

RubyMine gobbles up memory. 30 minutes of editing the rails codebase and it is using 703 MB of RAM! Vim is using 11 MB of RAM. RubyMine is slow to startup, and has occasional performance hiccups too. Vim wins.

Cost


RubyMine costs 100$ for a commercial license. Vim is open source. Good Karma. Vim wins.

Learning Curve


Vim requires you to know all sorts of arcane commands and to be really productive you need lots of plugins. So the learning curve is quite steep. RM has a much more intuitive interface and is ready to go out of the box. Edge RM

Conclusion

Ok, RM wins but with an asterisk. RM has the advantage of being completely focused on Ruby, HTML and JavaScript. It does one thing and does it well. Vim on the other hand will happily highlight and edit nearly every programming language or filetype known to man (or machine). 20 years down the road when Rails is a dinosaur, the new COBOL, and you have moved on to working in language X, your RubyMine skills will be irrelevant while the Vim you picked up might still be serving you well... But yea, most people will probably be slightly more productive in RubyMine. So what do you do? I don't know, so I say just learn them both and use them both.