Fork me on GitHub

Archive for the ‘General’ Category

Stop Complaining. Start Contributing!

Tuesday, May 24th, 2011

Because I maintain several open source projects on Github I’m constantly getting emailed questions or issues, or people are always opening up tickets with bugs, issues, complaints, etc… And I really appreciate the feedback on these projects, I really do. What I would appreciate more is if instead of just opening a ticket, or sending an email, why not fork the project, fix it, and then contact me?

Now, I know that sounds like a lot of work, but honestly it’s really not. Github has made contributing to open source projects so trivial that everyone should be doing it. Take for example a recent ticket I got for one of my projects. The gist of ticket was that if there was a space in the project name the library would throw an error. That’s a great bug! It’s also an incredibly easy one to fix. If the person who opened the ticket has actually just submitted a pull request with the fix instead the fix would already have been deployed. Granted it would’ve taken a bit more than the few minutes to open the ticket, but not that much more. [UPDATE: He actually did fork the project and is trying to fix it! Awesome!]

So why should you do this? Why should you take the time to fix your own issues instead of having the library owner/maintainer do it? Well, the reasons are plentiful, but here are a few of my favorites:

  • You can have it now! That’s right, if you fork the project and fix the bug or add that new feature you can start using today! Even before the project owner has a chance to merge in the pull request. That’s a total win right there!
  • Quicker to be released to the general public. Maintainers of open source projects are busy people and, usually, don’t spend all day working on their open source libraries. If someone submits a good patch or feature then it’s easier for them to pull it in and get it out as a proper release sooner.
  • It feels good! It feels really good to contribute back to a project that you use often. After awhile you might even get commit rights to the project and won’t have to maintain a fork. That feels really good!
  • Build a name for yourself. That’s one of the ways you land better jobs or contracts. People start seeing your name floating around commit messages. You get to know the people maintaining the projects, they like your work, then when they’re looking to fill a position, guess who they think of?
  • It makes you a better developer. By contributing to different projects you learn different techniques. You get to understand the code of the library you’re using and learn little tricks that you might not have known about otherwise.

Those are just a few of the reasons why giving back to the open source community is great. So the question I’m going to leave you with now is are you going to be a player or a hater? Someone who just complains all day, or someone who helps to make the world a better place? I’m hoping you become the latter.

Project, Issue, and Error Tracking United!

Monday, April 25th, 2011

For the last few years every project or company I’ve worked for has started the same way, by setting up Basecamp, Lighthouse and Hoptoad (or similar ones anyway). Why? Basecamp  - so we could share documents and todos. Lighthouse – so we could track our issues and bugs. Hoptoad – so we could track the errors our application was generating.

These are all very good applications and have served myself and my clients well, but they’ve suffered from several very big flaws. The first big flaw was the cost. You can easily drop $100 or more a month across these different services. But that wasn’t the biggest flaw or problem I’ve had with these services. The biggest problem was lack of integration.

So what do I mean by lack of integration? Well, when an error comes in I want to easily be able to create a new issue from it. When the issue gets resolved, so should the error. If the error reoccurs it should re-open automatically, and so should the issue. I want to be able to create an issue right from a document or be able to attach issues to a document. I should be able to follow the flow from document to issue to error and back again very easily. Unfortunately, these applications don’t give you that level of integration. They offer some level, but just not enough.

Well, my friends, welcome to the future. Welcome to FluxTracker.com. FluxTracker combines a great issue tracker, a project management system, and an error tracker all in one application. Now you can full integration without any configuration, oh, and you can do it at a fraction of the cost!

We know it isn’t easy to switch to a different application, that’s why we’ve made it easy for you. You can easily import your Lighthouse account. FluxTracker also allows you to easily use the Hoptoad Notifier plugin for your project by just setting a few configuration parameters.

So know you know, you’re life can be easier. And you now know how easy it is to get started! So what are you waiting for? Go and sign up for our Free plan and start living the dream.

Because everybody has an opinion…

Friday, April 15th, 2011

In case you’ve been living in a cave this week you’ve probably heard that Ruby on Rails is going to be including both the CoffeeScript and SASS libraries, it will also make jQuery the default JavaScript framework, replacing the Prototype framework.

I would like to start by addressing my experiences with CoffeeScript. My opinion of it is of ambivalence. I’ve used it on a project, I’ve played with and in the end I’ve come out with the opinion of “it’s ok”. It didn’t blow me away, but at the same time I can see why so many people like. It offers some really cool features that I really wish JavaScript had and you can cut down on the amount of code you have to write. On the other hand the apps I tend to write don’t tend to be that JavaScript heavy that I really needed to reach out for something like CoffeeScript.

So, how do I feel about CoffeeScript being included with Rails? Well, I’ll get to that. Let’s go over some of the most common arguments I’ve heard from people this week about why they’re anti-CoffeeScript in Rails.

“It’s an abstraction layer of JavaScript! JavaScript isn’t that bad, why can’t you just write JavaScript?”

“It’s going to be a hinderance to newbies. It’ll be too much of a learning curve!”

Let’s start with that second point first, shall we? I agree, it does represent a new element that needs to be learned when coming to Rails. But here’s the pretty nifty thing about how it’s all implemented in Rails. In order to actually use CoffeeScript in Rails you have to create your files named foo.js.coffee if, however, you just name your file foo.js then, guess what? You will have to write plain old JavaScript! Seems like newbies, and those who don’t like CoffeeScript, can just keep writing plain old JavaScript without anything stopping them at all.

Now, let’s talk about the abstraction layer argument. Yes, CoffeeScript is an abstraction on top of JavaScript, but let’s take a look at a few other parts of the Rails stack and see how they hold up against this argument.

Here’s a fairly common Rails stack:

  • ActiveRecord
  • Haml
  • jQuery
  • RSpec

What do all those things have in common? Well, they’re all abstraction layers that sit on top of something else, don’t they? Let’s look at that list again?

  • ActiveRecord – SQL (Structured Query Language)
  • Haml – HTML
  • jQuery – JavaScript, you could just as easily hand roll those AJAX calls in pure JavaScript.
  • RSpec – Test/Unit

What I’ve found funny about the particular argument is that I’ve heard it MOST from those who use things like HAML, which is a DEFINITELY an abstraction layer that sits on top of HTML. See where I’m going with this one? Good, I don’t want to belabor the point. :)

So, finally, where do I stand on this whole thing? Well, I view like it Test/Unit and Prototype. Those are both the current standard (although jQuery will replace Prototype in 3.1) and I don’t like or use either of them. Instead I configure Rails to use jQuery and RSpec. I don’t like Haml, but those that do simply replace ERB with Haml and they move on with their day. So my take is this, it’s there, it’s included. Use it if you like, or don’t. Is it really that big a deal? No, it really isn’t. If Rails dropped ERB and went with Haml as the default, would I bitch and moan, probably a bit, but then I’d just install the Rails-ERB gem and move on with my day, just like I do with jQuery and RSpec today.

So sit back, relax, use the libraries that you want to use, Rails let’s you do that. Oh, while you’re relaxing why not try out CoffeeScript, who knows, you might just enjoy it. Or not.

 

Testing Tools Aren’t All the Same, Choose Wisely

Friday, March 4th, 2011

“Testing is painful.”

“Testing is hard.”

“Testing is complicated.”

“Testing is not fun.”

I hear those sorts of things all the time when I talk to people about testing. I agree that sometimes testing can be all of those things, but if you choose the right tools, the tools that best suite you, testing doesn’t have to be. Let me give you an example of what I’m talking about, how choosing the right tools can make a huge impact on how you feel about testing.

When working for a client recently I came across the need for end to end integration testing. I needed to test, amongst other things, the flow of a user registering through the application in a few different ways. Because registration behaves differently based on where you come from and where you want to go, I needed a good way to test that entire flow, so simple unit and functional tests just were not going to cut it.

In the Ruby community there is a big push to use a testing framework called, Cucumber. Cucumber is a behavior driven development (BDD) tool that let’s you write user stories in plain English. Those stories then get translated into Ruby code that tests those stories against your application. Because of it’s popularity, and some of it’s quite amazing features, this was my first stop on the path to integration testing bliss.

Let me give you an example of a Cucumber script:

Feature: Registration
In order to use My Great Application
As a user
I want to be able to register
Scenario: 'Standard Registration'
Given I am not currently logged in
When I am on the signup page
Then I should see "Sign Up"
And I fill in "Name (required)" with "Mickey Dolenz"
And I fill in "Email (required)" with "mickey@monkees.com"
And I fill in "Password (required)" with "password"
And I fill in "Password confirmation" with "password"
And I press "Register"
Then I should see "Sign Up - Confirm Your Account"
Then I should be on the registration thank you page
Then "mickey@monkees.com" should receive an email
When I open the email
Then I should see "Confirm my account" in the email body
When I follow "Confirm my account" in the email
Then I should be on the welcome page
And I should see "Welcome to the Great Application"
Scenario: 'Accepting an invitation'
Given I am not currently logged in
And the "Boys and Girls Club" invites "mickey@monkees.com" to join
Then "mickey@monkees.com" should receive an email
When I open the email
Then I should see "Accept Invitation" in the email body
When I follow "Accept Invitation" in the email
Then I should be on the signup page
Then I should see "Sign Up"
And I fill in "Name (required)" with "Mickey Dolenz"
And the "Email (required)" field should contain "mickey@monkees.com"
And I fill in "Password (required)" with "password"
And I fill in "Password confirmation" with "password"
And I press "Register"
Then the account "mickey@monkees.com" should be "activated"
Then I should be on the accept/decline invitation page
And I should see "Join the Boys and Girls Club"

That script tests the user registration flow through an application in a couple of different ways, first through ‘standard’ registration, and then through being invited to join. Now, the beauty of Cucumber is that these scripts are ‘human’ readable. Your product manager, or other stake holders, should be able to write these scripts themselves, and you, the developer, should be able to just plug them in and code until those scripts pass.

Unfortunately, while that sounds like a little slice of Heaven, the reality is far from it in practice. First, getting stake holders to actually write these ‘stories’, as their typically called, is a tough chore to begin with. If they do write them, they’re typically not going to be ‘plug and play’. Why? Well, when Cucumber reads these scripts it goes line by line and tries to find some code that matches the regular expression of that line and then execute it. If it doesn’t find matching code, then it fails. That means that your stake holders need to write these scripts in a very particular way or developers need to sit down and massage those stories to fit the correct regular expression.

Now, let me just take this opportunity to say that this is not a post about how much I hate Cucumber, in fact I think Cucumber is a pretty amazing piece of software, and does in fact have a lot of great uses. Instead, what I’m talking about it is how Cucumber turned out not to be the right tool for the job for me on a recent project.

So why wasn’t Cucumber the right tool for the job? Great question, glad you asked. Cucumber turned out not to be the right tool for a few reasons. The biggest of which was that I was the one who was writing the user stories. The stake holders had no desire to write these stories, which meant I had to write them. The I had to write the ‘steps’ that back each line of the script. In all fairness, Cucumber does give you some great steps right out of the box. After some fiddling I finally got the Cucumber scripts up and running and testing my work flow. But I definitely ran into some issues.

Because Cucumber isn’t pure Ruby I had a hard time doing something as simple as just printing out the request’s body and headers without having to write a step that did just that, then add that step to my story, etc… It’s overall fiddlyness and non-intuitive way of doing things caused me a lot of grief and time. And, most importantly, I wasn’t really getting the big benefit of Cucumber, stake holder’s writing the stories. So I was doing all this work and not getting the benefits of Cucumber.

So what did I do? I turned to a library called Steak. Steak allows you to write integration tests using pure Ruby and integrates directly in with RSpec, my preferred testing framework. With Steak I was able to write my integration tests in just a few minutes.

require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper')

feature "Registration Steak", %q{
In order to use My Great Application
As a user
I want to be able to register
} do

  scenario "register throught the standard registration process" do
    visit signup_path
    
    expect {
      fill_in_registration(:name => 'Mickey Dolenz', :email => 'mickey@monkees.com')
    }.to change(delivered_emails, :size).by(1)
    
    user = User.find_by_email('mickey@monkees.com')
    user.should be_unverified
    
    page.should have_content('You have signed up successfully. However, we could not sign you in because your account is unconfirmed.')
    current_path.should == root_path
    
    visit signin_path
    fill_in 'user_email', :with => 'mickey@monkees.com'
    fill_in 'user_password', :with => 'password'
    click_button 'Sign In'
    
    page.should have_content('You have to confirm your account before continuing.')
    current_path.should == new_user_session_path

    click_email_link_matching(/users\/confirmation/, delivered_emails.first)

    current_path.should == welcome_users_path
    page.should have_content('Welcome to the Great Application')
    user.reload
    user.should be_activated
  end
  
  scenario "register from an invitation" do
    mark = users(:mark)
    organization = mark.organizations.first
    signin(mark)
    
    visit new_organization_invitation_path(organization)
    expect {
      expect {
        fill_in 'organization_invitation_worker_emails', :with => 'mickey@monkees.com'
        click_button 'Send Invites'
        DJ.first.invoke_job
      }.to change(delivered_emails, :size).by(1)
    }.to change(organization.invitations, :count).by(1)
    
    invitation = organization.invitations.first
    
    signout
    
    click_first_link_in_email(delivered_emails.first)
    
    current_path.should == signup_path

    fill_in_registration(:name => 'Mickey Dolenz')
    
    current_path.should == organization_invitation_path(organization, invitation)
    
    user = User.find_by_email('mickey@monkees.com')
    user.should be_activated
    
    expect {
      click_on 'Get Started Now!'
    }.to change(user.organizations, :count).by(1)
    
    current_path.should == organization_campaign_path(organization, organization.campaigns.first)
  end
  
end

While my Steak scripts a bit more wordy and are definitely not ‘human’ readable and editable by stakeholders, they did achieve my goal of allowing me to write integration tests quickly.

So here you see I picked a very powerful tool, that has a lot of great benefits, Cucumber, but I picked it for the wrong reasons. I picked it because it was popular, and not because it would help me achieve my goals. If my goals where to have stakeholders write the stories and hand them off to development, than it would’ve been a better choice. But in the end my goal was to write integration tests and write them quickly, which is why Steak ended up being the right tool for that job.

This has all been a really long winded way of saying doing some research before choosing your testing frameworks, or any framework for that matter. Play with it, research it, make sure it meets your goals, not somebody else’s. If you choose the right tools then testing doesn’t need to be scary, complicated, frustrating, etc… Testing is a requirement and a must have, so why not make it fun?

Building Interfaces and Abstract Classes in Ruby

Monday, February 7th, 2011

So back in the dark ages of my career, pre-2006, I spent a long time coding Java. Yeah, I know, please don’t judge. Anyway, In Java, for those of you who are unaware were two constructs that I occasionally wish I had in Ruby, those are Interfaces and Abstract Classes. The difference between these two constructs is subtle, but important.

In Java an Interface is a basically a blueprint of methods that the class who implements the Interface needs to implement. For example:

interface Bicycle {

  void changeGear(int newValue);

  void speedUp(int increment);

  void applyBrakes(int decrement);
}

public class ACMEBicycle implements Bicycle {
   
   public void changeGear(int newValue) {
     // do some work here
   }
   
   public void speedUp(int increment) {
     // do some work here
   }
   
   public void applyBrakes(int decrement) {
     // do some work here
   }

}

Here we have a Bicycle Interface that says there are three methods that need to be implemented. It is then the responsibility of the ACMEBicycle class to implement those methods. Now, an Abstract Class in Java is similar to an Interface in that it too is a blueprint of methods that the extending class may or may not need to implement. There in lies one of the differences between the two. Let’s take a look at the same example, but this time we want to implement the same behavior of all of our extending classes for the applyBrakes method:

abstract class Bicycle {
  
  abstract public void changeGear(int newValue);

  abstract public void speedUp(int increment);

  public void applyBrakes(int decrement) {
    // do some work here
  }
  
}

public class ACMEBicycle extends Bicycle {
   
   public void applyBrakes(int decrement) {
     // do some work here
   }

}

An Abstract Class is a great way to provide a mix of fully implemented methods as well as providing subclasses with a mixture of methods that need to be implemented by the extending class.

The really powerful part of all of this is two fold. First, the Java compiler will happily yell at you and fail if it finds that you haven’t implemented some of the methods that you were told you had to. Second, you can easily see the methods that you need to document right there, you can even copy/paste their definitions right into your class so you can start to fill them out.

So, how does this bring us over to Ruby? Great question. I’d like to take a few moments and explore a few ways we can get some of this power in Ruby.

Unfortunately, or fortunately depending on how you look at it (I see it as a mixed blessing), there is no compiler in Ruby, so we don’t really have a good way of having the system yell at us if we don’t implement the methods we were supposed to. But, there is still plenty we can do to help those who are implementing our classes both know what they need to implement and to find out what they haven’t implemented when their program is executing.

Here is one implementation on we can gain a bit of that functionality back in Ruby:

module AbstractInterface
  
  class InterfaceNotImplementedError < NoMethodError
  end
  
  def self.included(klass)
    klass.send(:include, AbstractInterface::Methods)
    klass.send(:extend, AbstractInterface::Methods)
  end
  
  module Methods
    
    def api_not_implemented(klass)
      caller.first.match(/in \`(.+)\'/)
      method_name = $1
      raise AbstractInterface::InterfaceNotImplementedError.new("#{klass.class.name} needs to implement '#{method_name}' for interface #{self.name}!")
    end
    
  end
  
end

class Bicycle
  include AbstractInterface
  
  # Some documentation on the change_gear method
  def change_gear(new_value)
    Bicycle.api_not_implemented(self)
  end
  
  # Some documentation on the speed_up method
  def speed_up(increment)
    Bicycle.api_not_implemented(self)
  end
  
  # Some documentation on the apply_brakes method
  def apply_brakes(decrement)
    # do some work here
  end
  
end

class AcmeBicycle < Bicycle
end

bike = AcmeBicycle.new
bike.change_gear(1) # AbstractInterface::InterfaceNotImplementedError: AcmeBicycle needs to implement 'change_gear' for interface Bicycle!
view raw gistfile1.rb This Gist brought to you by GitHub.

What we’ve done here is to inject a Module into our Bicycle class to give it a nice error it can raise and a little bit of help building a nice error message for the user. Then in our Bicycle class we define all the methods we want and in the ones we need the end user to define we can call the api_not_implemented method and it will raise the AbstractInterface::InterfaceNotImplementedError error for us.

We could simplify this a bit by having a nice little helper macro that we can use to build these methods, like this:

module AbstractInterface
  
  class InterfaceNotImplementedError < NoMethodError
  end
  
  def self.included(klass)
    klass.send(:include, AbstractInterface::Methods)
    klass.send(:extend, AbstractInterface::Methods)
    klass.send(:extend, AbstractInterface::ClassMethods)
  end
  
  module Methods
    
    def api_not_implemented(klass, method_name = nil)
      if method_name.nil?
        caller.first.match(/in \`(.+)\'/)
        method_name = $1
      end
      raise AbstractInterface::InterfaceNotImplementedError.new("#{klass.class.name} needs to implement '#{method_name}' for interface #{self.name}!")
    end
    
  end
  
  module ClassMethods
    
    def needs_implementation(name, *args)
      self.class_eval do
        define_method(name) do |*args|
          Bicycle.api_not_implemented(self, name)
        end
      end
    end
    
  end
  
end

class Bicycle
  include AbstractInterface
  
  needs_implementation :change_gear, :new_value
  needs_implementation :speed_up, :increment
  
  # Some documentation on the apply_brakes method
  def apply_brakes(decrement)
    # do some work here
  end
  
end

class AcmeBicycle < Bicycle
end

bike = AcmeBicycle.new
bike.change_gear(1) # AbstractInterface::InterfaceNotImplementedError: AcmeBicycle needs to implement 'change_gear' for interface Bicycle!
view raw gistfile1.rb This Gist brought to you by GitHub.

That approach certainly makes our code look a bit cleaner, I’m not denying that, however it has one really big flaw, at least for me anyway, it doesn’t give us a good to place to hang our documentation hat. In the previous approach we had actual methods that we could then document and that documentation would then show up in RDoc when it’s outputted. With the latter approach, however, we can document the hell out of the needs_implementation calls we have in the Bicycle class, but they won’t ever show up in the documentation. That means that users of our library have to crack open the actual code itself to see what it they are expected to implement.

Another approach we could’ve taken, which I bother to demonstrate here as I don’t think it offers a better approach is to have the needs_implementation method collect up the names of those methods and use method_missing to report that the method needs to be implemented. I mention it here only for completeness, but it definitely is not the best solution to this problem.

Finally, I would like to note that, as far as I can see, there is no way in Ruby to create a callback hook for when a class has been defined. If there was in fact such a hook we could use to it immediately notify the end user that they have forgotten to implement certain methods. Perhaps in Ruby 2.0??? That’s just pure hope on my part.

That’s it. I hope you enjoyed our brief (*cough*) look through implementing Interface and Abstract Classes in Ruby. I hope you’ve enjoyed it.

* PS, yes, I’m aware I didn’t talk about multiple vs. single inheritance in either Java or Ruby, nor did I talk about the fact that in Ruby you can’t really have Abstract Classes. I thought that was all a bit much for an already rather lengthy post as it was. Perhaps another day. :)