| I see this assertion increasingly frequently, and it puzzles me: that if we're not currently using an object to encapsulate state, we should prefer class methods. What's the justification? Other than four characters saved (".new"), what's the benefit in this approach? State encapsulation is just one feature of objects. We may not be using it right now, but the only thing you achieve with the above code is removing future flexibility. It costs us nothing to allow for the future possibility of encapsulated state, so why rule it out? Adding complexity when you don't yet need it, fine, I quite understand objecting to that; but here you're actually putting in effort to make a future modification more difficult. Funnily enough, Code Climate's previous blog entry was on precisely this topic, and is worth a read: http://blog.codeclimate.com/blog/2012/11/14/why-ruby-class-m... For what it's worth, I don't see the point in instantiating a whole new spam checker for every piece of content, so I'd probably change the OP's example to read: class UserContentSpamChecker
TRIGGER_KEYWORDS = %w(viagra acne adult loans xrated).to_set
def is_spam?(content)
flagged_words(content).present?
end
protected
def flagged_words(content)
TRIGGER_KEYWORDS & content.split
end
end
If I really really wanted access to a default spam checker via a global constant I can always add the following: class UserContentSpamChecker
def self.is_spam?(content)
new.is_spam?(content)
end
end
At least then if my UserContentSpamChecker class ever has to change (perhaps it starts to use an external spam-checking service that's injected through the constructor), then I only need to change code in one place. And other clients that might want to inject a different spam-checking service (or a test double) are perfectly able to. |
Then we can argue on the best way to handle that namespace. I'm not particularly fond of the class method approach neither but I don't think that your approach is appropriate either. A namespace should be instantiated only once in my opinion, that's why I'm going for the singleton object. Maybe the problem is with ruby and it should provide another mechanism for managing namespaces ?