[英]ruby's Regexp.last_match global value inside method
誰能解釋以下原因為何不起作用? 每當進行正則表達式匹配時,不是$~
應該是全局變量集嗎?
class LocalizedObject < BasicObject
def initialize(hash)
@hash=hash
end
def method_missing(name, *args)
@hash[$current_locale || "en"].send(name, *args)
end
end
proxy = LocalizedObject.new({"en" => "foobarbaz", "pt" => "xpto"})
proxy # => "foobarbaz"
# this won't work as expected
proxy.match(/f.*r/) # => #<MatchData "foobar">
Regexp.last_match # => nil
$~ # => nil
# which would be like this...
"foobarbaz".match(/b.*z/) # => #<MatchData "barbaz">
Regexp.last_match # => #<MatchData "barbaz">
$~ # => #<MatchData "barbaz">
編輯:我用更想要解釋的東西代替了之前的簡單示例。...我希望LocalizedObject對用戶透明,因此可以將其插入到一些我不想更改的現有代碼中。
誰能想到使這項工作有效的技巧?
我為此使用ruby 1.9.2,但是我從1.8.7和從https://github.com/jeremyevans/sequel/blob/master/lib/sequel/sql.rb被盜的自定義BasicObject
獲得了相同的BasicObject
在re.c的 3453行中,提到:
注意,
last_match
對於執行模式匹配的方法的線程和方法范圍是局部的。
由於使用代理對象,您正在method_missing
中進行match
調用,因此只要將其更改為,就可以看到蜜蜂。
def method_missing(name, *args)
res = @object.send(name, *args)
Kernel.p $~
res
end
更新:
相當丑陋,但也許這樣的選擇是可行的?
#!/usr/local/bin/ruby19
def set_current_locale(l)
$current_locale = l
ObjectSpace.each_object { | obj |
obj.adjust_locale if obj.respond_to? :adjust_locale
}
end
class LocalizedObject < String
def initialize(hash)
super(hash[$current_locale || "en"])
@hash = hash
end
def adjust_locale
self[0..-1] = @hash[$current_locale || "en"] if @hash
end
end
proxy = LocalizedObject.new({"en" => "foobarbaz", "pt" => "xpto"})
proxy.match(/f.*r/) # => #<MatchData "foobar">
Regexp.last_match # => #<MatchData "foobar">
$~ # => #<MatchData "foobar">
set_current_locale('pt')
proxy.match(/x.*o/) # => #<MatchData "xpto">
Regexp.last_match # => #<MatchData "xpto">
$~ # => #<MatchData "xpto">
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.