./databyte


Use the debugger, not puts

I’m going over the backlog of Ruby Rogues and I came across some very interesting comments in Episode 7 on Debugging in Ruby. There are indeed two types of people, those that use puts and those that use the debugger.

I find it hilarious that Charles has to convince everyone else that using the debugger isn’t harder than puts. Almost everyone else uses puts instead of debugging and I find that interesting. My personal opinion is that most people find puts easier because they’re actually uncomfortable or unfamiliar with debugger.

More than puts

Debugger is just as easy to use as puts. In fact, I would say debugger is easier because if you guessed wrong on which object to print out, you can try another and another until you find it. The key isn’t that the debugger is just an interactive console to constantly print out objects, it can do so much more.

Printing out statements into a log file works well when you have a lot of data to process. However, if you’re trying to track down a specific bug or just trying to get your code to run right, the best option has to be the debugger. You simply don’t know what to print out and you’re just guessing along the way.

Why you should still use puts

There is however a place where the debugger doesn’t work well and you do print out a lot of data into log files, that’s with threading. Threading is much harder to track down problems with when using a single interactive debugger. The C/C++, .NET and Java developer in me knows how hard it is to get the debugger working just right and especially in threading issues, just simply print out a lot of statements can be easier. (Though the debugger for threading in .NET is one of the best ones out there.)

Don’t make that be the reason to ignore it in Ruby. Treat the debugger more like how you would try to work with an assembler application. There’s less information to process out of a simpler application.

Let’s do this!

If you’re ready, we have to setup our basic environment. Don’t bother with ruby-debug and instead just use debugger which is available on GitHub.

gem install debugger

# or in your Gemfile
gem 'debugger'

In your ~/.rdebugrc file, you have to set:

set autolist
set autoeval
set autoreload

I also have in my config:

set forcestep

Instead of puts @foo, just use a debugger call. I won’t go into the details of using the debugger since Pivotal Labs wrote a good HOWTO and there’s a rdebug cheat sheet.

I HAZ DEBUGGER!

As with my last blog article, I’m going to use a few examples of debugging in RABL.

In Issue #249, I explain using debugger to poke at your object:

glue :user do
  attributes :username => :author_name

  node :debug_me do
    debugger
  end
  child :phone_numbers => :pnumbers do
    extends "users/phone_number"
  end
end

# pops out:

(rdb:1) v l
  block => #<Proc:0x007fed82628488@/Users/databyte/projects/popular/rabl/fixtures/rails3_2/app/views/posts/show.rabl:14>
  name => :debug_me
  options => {}
  result => 1
(rdb:1) @_object
#<User id: 1924, username: "billybob", email: "billy@bob.com", location: "SF", is_admin: false, created_at: "2012-05-24 05:51:59", updated_at: "2012-05-24 05:51:59">
(rdb:1) @_object.phone_numbers
[#<PhoneNumber id: 2565, user_id: 1924, is_primary: true, area_code: "222", prefix: "000", suffix: "6666", name: "Home">, #<PhoneNumber id: 2566, user_id: 1924, is_primary: false, area_code: "222", prefix: "000", suffix: "6666", name: "Work">]

In Issue #243, I explain using source_location to find where a method is being defined but first we have to debug directly into the RABL gem.

subl `bundle show rabl`
# or whatever editor you use
mvim `bundle show rabl`
mate `bundle show rabl`

# or if your editor is set right:
bundle open rabl

And once you have RABL open - put a debugger statement in and restart your application since external libraries are not reloaded. Using the debugger here is a loads more efficient than placing puts everywhere and constantly restarting your application.

[193, 202] in /Users/databyte/projects/popular/rabl/lib/rabl/engine.rb
   193      # Returns a guess at the default object for this template
   194      # default_object => @user
   195      def default_object
   196        if context_scope.respond_to?(:controller)
   197          debugger
=> 198          controller_name = context_scope.controller.controller_name
   199          stripped_name = controller_name.split(%r{::|\/}).last
   200          instance_variable_get("@#{stripped_name}")
   201        end
   202      end
/Users/databyte/projects/popular/rabl/lib/rabl/engine.rb:198
controller_name = context_scope.controller.controller_name

(rdb:1) context_scope.controller.method(:controller_name).source_location
["/Users/databyte/.rvm/gems/ruby-1.9.3-p194-perf/gems/actionpack-3.2.3/lib/action_controller/metal.rb", 121]

Use your debugger and get your Ruby-fu in order then abuse what Ruby gives you.


Testing in isolation, example in RABL

SOLID, Dependency Inversion principle, testing doubles, presenters, decorators, composites, oh my!

Now that I have your attention with a bunch of fancy words, let’s apply them to a real problem. I’ve closed a lot of recent issues for RABL on “limitations” of how RABL supports syntax for multiple variables and conditions. The problem basically boils down to ignoring the SOLID principles.

RABL

If you’re not familiar with RABL, it’s a template rendering engine similar to ERB but tuned for structured outputs like JSON and XML.

RABL allows you to have a main object that everything is built around. However, there are pull requests for passing locals and passing objects to allow conditionals within blocks. There’s also a slew of issues that mostly deal with syntax problems for making RABL do things you shouldn’t allow your views to do in the first place.

Here’s an example:

# post_controller.rb
def show
  @post = Post.find(params[:id])
end

# show.rabl
object @post

attributes :title, :body

child :author do
  # root_object is a hack for accessing @post
  attribute :name => :author_name unless root_object.author == current_user
end

node :publication_date do |post|
  if post.status == 'published'
    post.published_date
  end
end

Presenters, Decorators and Composites

If you’re not sure what the differences between the wrappers are, I highly suggest reading an article by Thoughtbot that covers Decorators compared to Strategies, Composites, and Presenters. I’m going to combine two of those to make a presentable decorator:

# post_presenter.rb
class PostPresenter < Draper::Base
  decorates :post
  attr_reader :current_user

  def initialize(post, current_user)
    super(post)
    @current_user = current_user
  end

  def author_name
    author.name unless author == @current_user
  end

  def publication_date
    publication_date if status == 'published'
  end
end

# post_controller.rb
def show
  @post = PostPresenter.new(Post.find(params[:id]), current_user)
end

# show.rabl
object @post

attributes :title, :body, :author_name, :publication_date

Oh my, look at how easy that view is now!

If the attributes are nil, RABL will simply skip over them. It’s like your own free Null Object. (Explanation of Null Object and a couple others just in case.)

If you don’t want to use Draper, you can just break the Law of Demeter a little and go with a plain object that requires accessing the instance variables through the presenter:

class PostPresenter
  attr_reader :post, :current_user

  def initialize(post, current_user)
    @post = post
    @current_user = current_user
  end
end

Or you can use four other methods of decorating in Ruby.

Those four examples of decorating though didn’t cover the simple delegates. So you can also use the Delegate class in Rails:

class PostPresenter
  attr_accessor :post
  attr_accessor :current_user

  delegate :title, :body, :author, :publication_date, to: :post
  def_delegators :@current_user, :name, to: :current_user

  def initialize(post, current_user)
    @post = post
    @current_user = current_user
  end
end

Or in plain Ruby, use Forwardable:

require 'forwardable'

class PostPresenter
  extend Forwardable
  def_delegators :@post, :title, :body, :author, :publication_date
  def_delegators :@current_user, :name

  def initialize(post, current_user)
    @post = post
    @current_user = current_user
  end
end

Read more about delegation in Ruby.

Dependency Inversion (the D in SOLID) used for testing

Now that I don’t have logic embedded within my view, I don’t even need to unit test them. I should still have my controller verify that the proper template was rendered and I need some basic level of integration testing but overall, I can skip view rendering.

To test my “RABL”, I actually test my presenter. To test my presenter, I use Dependency Injection to supply my presenter with the objects I need it to test with.

Gregory Brown talks about Dependency Inversion in Issue #23: SOLID Design Principles of Ruby Best Practices. The problem with his examples and my example above is we’re actually demonstrating Dependency Injection and not Inversion. An article on RubySource titled SOLID Ruby: Dependency Inversion Principle does a better job of explaining the differences between the two. It basically boils down to initializing the object with your dependencies versus calling methods with your dependencies passed in. Either way, it’s the same damn thing. You’re abstracting the interface between different implementations which makes it easier to change and test.

Test Doubles (Stubs and Mocks)

This is ultimately the entire point of this article. You have successfully segregated your dependency on multiple instance variables, random helper methods and anything else floating around in your scopes. When a view refers to foo or bar, you can look at the presenter to know exactly where that is coming from.

It also makes it possible to use stubs and mocks to easily swap out parts of the presenter for testing. You don’t have to actually have a current_user, just mock(:current_user). You can also really speed up your tests by not using fixtures or factories to build out your user or post. Have post be Post.new with method stubs where needed.

RABL Issue #299 asks:

... we want to use current_user in our renderer ...
... it doesn't cover having, say, a current_user method in use ...

Now that’s easy. Pass in whatever current_user you want to use to your presenter.

One last example…

Are you using the Timecop gem to manipulate your clock for testing? Just pass in a Time object:

class PostPublishPresenter
  include ActionView::Helpers::DateHelper

  def initialize(published_at)
    @published_at = published_at
  end

  def age(to_when = Time.now.utc)
    distance_of_time_in_words @published_at, to_when
  end
end

>> foo = PostPublishPresenter.new(Time.now.utc - 2.days)

>> foo.age
=> "2 days"

>> foo = PostPublishPresenter.new(Time.now.utc - 14.hours)

>> foo.age
=> "about 14 hours"

>> foo.age(Time.now.utc - 14.hours)
=> "less than a minute"

Government Software is Public Domain

My twitter friends @haacked and @dbness both tweeting out this from @anildash:

Software created with our tax dollars should be open source so we can use & improve it.

All software by the government is Public Domain.

The Freedom of Information Act (FOIA) gives all citizens the right to request something from the government. Back in 2003, I was working at Dialog Medical and we started selling our informed consent software to hospitals, including the VA. So I filled out my FOIA request and sure enough a month later, I received a CD with a copy of the VA’s EMR - known as VistA. This is the real VistA before that other crappy Vista.

As I dug deeper into VistA and needed help, I turned to the online communities of WorldVistA and Hardhats. These groups have taken the freely available, unrestricted and open copy of our government’s software and they would install it at non-federal government hospitals.

WordVistA lists several adopters and last I heard from people in the field, the installs at the American Somaon government and Indian Health Services are some of the more active installs. I even knew a geeky doctor that installed it at his own small practice.

The government doesn’t take pull requests.

The problem with this approach though is that once you request software via FOIA, you’re basically creating a fork. Someone on the outside of the government has to continually merge in changes from both sides or the government has to switch to an outside source. For VistA, it’s obviously the former since it’s a very large codebase and there are more developers working on it internally than externally.

The open government

I think what Anil Dash really wants to see is the government not only make their code available but to do so openly. To work on their code via GitHub and take in pull requests. It’s very possible to happen but it’s not going to be the White House being petitioned to do so.

Instead, I suggest that Anil Dash reach out to Todd Park, our Fed CTO. Work from the inside out by getting developers to join in on the fun. Come up with a plan to make government jobs as fulfilling and productive to the developer as a startup. I mean, of course government jobs gives you health insurance and sleep but it should also advance your career. Your work should be open, your labor should be rewarded and your options should be limitless.


Earlier →