Is Regexp.last_match thread safe?

The Ruby 1.9.2 platform docs state that calling Regexp.last_match is equivalent to reading the special $~ global variable.

From "The Ruby Programming Language", pg 318: "it is important to remember that $~ and the variables derived from it are all thread-local and method-local."

So Regexp.last_match is thread-safe. As for the other methods you are using in method_missing, I believe they are thread-safe as well. (If anybody knows differently, please edit this post.)


TL;DR

Yes, Regexp special global variables are thread-safe because they aren't truly globals. Despite the fact that the variables have the word "global" in the name, the documentation says:

These global variables are thread-local and method-local variables.

Threads

You can prove this to yourself in the irb or pry REPL. For example, to test the variables' scope inside threads:

# Ensure $~ and friends are nil in case this isn't a fresh REPL.
''.match /foo/

# Make this variable available inside the thread block.
thread_match = nil

Thread.new do
  'foo'.match /(foo)/
  thread_match = "In thread: #{$1.inspect}"
end

[thread_match, "Global value: #{$1.inspect}"]
#=> ["In thread: \"foo\"", "Global value: nil"]

Methods

These special variables aren't even truly global when used within a method. Consider the following:

def foo
  'foo'.match /(foo)/
  p $1
end 

[foo, $1]
#=> ["foo", nil]

Conclusion

In other words, the Regexp special variables look like true globals because of the $ prefix, but do not persist outside the enclosing thread or method. To what extent that justifies calling them "globals" at all is something you'd have to take up with the language designers, or file a bug about if you feel strongly that it's misleading.

Tags:

Ruby