Skip to content

Instantly share code, notes, and snippets.

@theotherzach
Created February 18, 2013 05:11
Show Gist options
  • Save theotherzach/4975241 to your computer and use it in GitHub Desktop.
Save theotherzach/4975241 to your computer and use it in GitHub Desktop.
class RockScore
NoScore = Class.new
def self.for_term(term)
positive = SearchEngine.count_results(%{"#{term} rocks"}).to_f
negative = SearchEngine.count_results(%{"#{term} sucks"}).to_f
score = 10 * positive / (positive + negative)
score.nan? ? NoScore : score
end
end
class ScoreCache
def self.for_term(term)
begin
CachedScore.for_term(term)
rescue CachedScore::NoScore
score = RockScore.for_term(term)
CachedScore.save_score(term, score)
score
end
end
end
class CachedScore < ActiveRecord::Base
attr_accessible :term, :score
class NoScore < RuntimeError; end
def self.for_term(term)
cached_score = find_by_term(term) or raise NoScore
result = cached_score.score
result || RockScore::NoScore
end
def self.save_score(term, score)
score = nil if score == RockScore::NoScore
create!(:term => term, :score => score)
end
end
@theotherzach
Copy link
Author

The RockScore::NoScore sentinel object is inert and returned instead of nil. The same if checks are needed for it as a nil but you get feedback as to where our no score came from.

The controller calls ScoreCache which is really the public interface here. Sorry if that's not super clear. This example is stolen from DestroyAllSoftware but I've been using the heck out of it at work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment