Thursday, December 23, 2010

Little Known Memoization Fact

Today I was writing a method for the Kata gem  to define the github api user.  A naive first approach to this might be:

def github_user
return @github_user unless @github_user.to_s.empty?
@github_user = %x{git config --get github.user}.chomp
@github_user = ENV['USER'] if @github_user.empty?
raise Exception, 'Undefined github user' if @github_user.empty?
end

It is is pretty straightforward what this method is doing.  If the github user has already been determined then return it to the caller.  Otherwise check the git config or use the environment to get the user.  Though straightforward it feels very clunky by referencing the instance variable each time in stepping through the logic.

A different approach would be to encapsulate the logic in a block and use memoization with the ||= operator.  Using this method all of the references to the instance variable can be removed and it is more obvious what your intention is:

def github_user
@github_user ||= begin
github_user, shell_user = %x{git config --get github.user}.chomp, ENV['USER'].to_s
raise Exception, 'Unable to determine github user' if (github_user + shell_user).empty?
github_user.empty? ? shell_user : github_user
end
end
view raw github_user.rb hosted with ❤ by GitHub