这是我正在看的代码:
def method_missing(id, *args)
return self.find(Regexp.last_match(1), args[0]) if id.id2name =~ /find_by_(.+)/
raise NoMethodError
end
Run Code Online (Sandbox Code Playgroud)
如果我有多个线程调用会发生什么Regexp.last_match?
如果我有多个线程使用该method_missing方法调用该对象会发生什么?
Ale*_*x D 24
Ruby 1.9.2平台文档声明调用Regexp.last_match等同于读取特殊的$~全局变量.
从"Ruby编程语言",第318页:"重要的是要记住$〜和从它派生的变量都是线程本地的和方法本地的."
因此Regexp.last_match 是线程安全的.至于你使用的其他方法method_missing,我相信它们也是线程安全的.(如果有人不同,请编辑这篇文章.)
是的,Regexp特殊全局变量是线程安全的,因为它们不是真正的全局变量。尽管这些变量的名称中都有“ global”一词,但文档中说:
这些全局变量是线程局部变量和方法局部变量。
您可以在irb或prep REPL中向自己证明这一点。例如,要测试变量在线程内的作用域:
# 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"]
Run Code Online (Sandbox Code Playgroud)
当在方法中使用时,这些特殊变量甚至不是真正的全局变量。考虑以下:
def foo
'foo'.match /(foo)/
p $1
end
[foo, $1]
#=> ["foo", nil]
Run Code Online (Sandbox Code Playgroud)
换句话说,由于前缀,Regexp特殊变量看起来像是真正的全局变量$,但不会在封闭的线程或方法之外持续存在。您必须在多大程度上证明将它们称为“全局变量”是合理的,您必须与语言设计师联系,或者提交有关您是否强烈认为它具有误导性的错误。