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.