Regexp.last_match线程安全吗?

这是我正在看的代码:

def method_missing(id, *args) return self.find(Regexp.last_match(1), args[0]) if id.id2name =~ /find_by_(.+)/ raise NoMethodError end 

如果我有多个线程调用Regexp.last_match会发生什么?

如果我有多个线程使用method_missing方法调用对象会发生什么?

Ruby 1.9.2平台文档声明调用Regexp.last_match等同于读取特殊的$~全局变量。

从“Ruby编程语言”,第318页:“重要的是要记住$〜和从它派生的变量都是线程本地的和方法本地的。”

所以Regexp.last_match 线程安全的。 至于你在method_missing中使用的其他方法,我相信它们也是线程安全的。 (如果有人不同,请编辑这篇文章。)

TL; DR

是的, Regexp特殊的全局变量是线程安全的,因为它们不是真正的全局变量。 尽管变量在名称中包含“global”一词,但文档说:

这些全局变量是线程局部变量和方法局部变量。

主题

你可以用irb或pry REPLcertificate这一点。 例如,要测试线程内变量的范围:

 # 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"] 

方法

在方法中使用时,这些特殊变量甚至不是真正的全局变量。 考虑以下:

 def foo 'foo'.match /(foo)/ p $1 end [foo, $1] #=> ["foo", nil] 

结论

换句话说,由于$前缀,Regexp特殊变量看起来像真正的全局变量,但是不要在封闭线程或方法之外保留。 在多大程度上certificate称他们为“全局”是你必须要接受语言设计师的事情,或者提出一个错误,如果你强烈认为这是误导性的。