簡體   English   中英

紅寶石的Regexp.last_match全局值里面方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM