让我告诉你try
是如何实现的。如果您想自己查看,请查看 activesupport 源。它在/lib/active_support/core_ext/object/try.rb中定义
class Object
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b)
end
end
end
这基本上做了什么,只是将方法名称和完整的参数发送到Object
. public_send
与 send 相同,但只能用于调用公共方法。
所以我重写了这个,以调试你的问题:
class Object
def try(*a)
result = public_send(*a)
puts $1.inspect
result
end
end
string = "Hello"
string.try(:match, /^(\w*)/)
puts $1.inspect
这输出
"Hello"
nil
所以出现了一个大问题:这是 ruby 解释器中的错误吗?. 也许。至少它没有记录在任何官方来源中。我找到了一个参考,告诉以下内容(请参阅全局变量。)
[...],$_
并$~
具有本地范围。它们的名称表明它们应该是全球性的,但这样更有用,而且使用这些名称是有历史原因的。
所以它似乎$1
也不是一个全局变量,即使它被内核报告为一个全局变量:
1.9.3-p194 :001 > global_variables
=> [:$;, :$-F, :$@, :$!, :$SAFE, :$~, :$&, :$`, :$', :$+, :$=, :$KCODE, :$-K,
:$,, :$/, :$-0, :$\, :$_, :$stdin, :$stdout, :$stderr, :$>, :$<, :$.,
:$FILENAME, :$-i, :$*, :$?, :$$, :$:, :$-I, :$LOAD_PATH, :$",
:$LOADED_FEATURES, :$VERBOSE, :$-v, :$-w, :$-W, :$DEBUG, :$-d, :$0,
:$PROGRAM_NAME, :$-p, :$-l, :$-a, :$binding, :$1, :$2, :$3, :$4, :$5, :$6,
:$7, :$8, :$9]
为了确保这一点,我将这种不一致转发给了 Ruby Bug Tracker。请参阅Ruby 错误 #6723