The clean! method has always worked correctly; however, as discussed above, the documentation for the method in the first release of Sanitize was misleading as to the method’s purpose. The documentation in later releases is correct:

clean!(html, config = {})
Performs Sanitize#clean in place, returning html, or nil if no changes were made.

The purpose of clean! is to sanitize the given string in place rather than returning a sanitized copy of the given string. In other words, it’s a destructive verson of clean.

It sounds like what you want is a method that tells you whether the given string needs to be sanitized, but doesn’t actually sanitize it. There currently isn’t a method that does this, but something like the following (which I imagine is similar to what you’ve hacked up) would work:

def is_dirty?(html)
  !Sanitize.clean!(html.dup).nil?
end

I’m curious what your use case for this is, though. If you’re trying to save processing time by not sanitizing already-clean strings, this won’t do the trick, since the only way to determine whether a string is dirty is to actually clean it (or a copy of it, as in the example above).