Skip to content


Subversion checkout URL

You can clone with
Download ZIP


Global variables for referencing submatches broken with ActiveSupport::SafeBuffer#gsub + block #3496

DerGuteMoritz opened this Issue · 2 comments

3 participants


When calling gsub with a block on an ActiveSupport::SafeBuffer the global variables $1, $2, etc. for referencing submatches are not always properly set (anymore?) when the block is called. So far I could only reproduce it when an ActiveSupport::SafeBuffer instance is passed to a method which in turn calls gsub with a block on it like this:

def foo(x)
  x.gsub(/(a)/) { |m| $1 + 'b' }

foo('a'.html_safe) # NoMethodError: undefined method `+' for nil:NilClass


foo('a') # => "ab"
'a'.gsub(/(a)/) { |m| $1 + 'b' } # => "ab"

This is true for Ruby 1.8.7-p352 and 1.9.2-p290 at least and affects at least Rails 3.0.x and 3.1.x.

fxn commented

Problem is $1 is not really global, despite the dollar. Their scope is controlled by ruby in a way that prevents AS::SafeBuffer from being able to provide gsub + block. For example, if you call a method that sets $1, the caller does not see that $1.

This has been reported several times, see for example #1555.

@fxn fxn closed this
xhh commented

i think what's confusing here it that calling gsub directly to an ActiveSupport::SafeBuffer instance works, but calling to a method argument doesn't work. if possible, the former should not work either (e.g. raise an exception). check

@igreg igreg referenced this issue from a commit
Commit has since been removed from the repository and is no longer available.
@NZKoz NZKoz referenced this issue from a commit in NZKoz/faraday
@radanskoric radanskoric Changed Faraday::Utils#escape to use block parameter instead of $1 to…
… sidestep a bug in ActiveSupport::SafeBuffer#gsub in Rails 3.1 (as described in rails/rails#3496)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.