HACKERS GONNA HACK
Undefined method `bytesize’ for nil:NilClass

This error (and a related one: undefined method `unpack’ for nil) threw me for a loop today. Here’s what I was trying to do:

    > s = ActionController::Base.helpers.strip_tags("foo:bar")
    => "foo:bar"
    > CGI.escape(s)
    NoMethodError: undefined method `bytesize' for nil:NilClass

Strange. Even less helpful was the error message that I’d get from calling the view helper url_escape on the string: undefined method `unpack’ for nil.  A quick Google search, however, revealed the issue (which you can read about here, here, and here).

Basically the issue is that you get an ActiveSupport::SafeBuffer, not a String, from strip_tags (and other helpers presumably) which is not compatible with CGI.escape or any method that internally makes use of $1, $2, etc. variables to perform string replacements.  This incompatibility has to do with the fact that SafeBuffer attempts to provide it’s own version of gsub which won’t work due to an interesting property of Ruby.

 ...the $_ and $~ variables (and related vars like $1, $&, etc) are "special", and only certain core class methods are able to modify them (in the caller's scope) while no Ruby code can. It is for this reason that you can't alias and wrap any of those methods without breaking them.

A simple fix for this is to call the to_str method on SafeBuffer before passing it into a method like CGI.escape like so:

    > s = ActionController::Base.helpers.strip_tags("foo:bar")
    => "foo:bar"
    > CGI.escape(s.to_str)
    => "foo:bar"