2013-01-16 26 views
-1

我在gsub!的替換參數內使用lambda。當以不同的方法定義lambda時,Regexp.last_match$~爲空,違背了lambda在調用時評估表達式的預期行爲。如果我運行這個代碼,我會得到一個錯誤,但是如果我在轉錄的第一行取消註釋,它就會起作用。當在另一種方法中定義lambda時,`lambda中的Regexp.last_match`調用爲`nil`

class Test 
    def initialize 
    @@replace = lambda { "#{callback('*', Regexp.last_match)}" } 
    end 

    def transcribe(s) 
    #@@replace = lambda { "#{callback('*', Regexp.last_match)}" } 
    s.gsub!(/(?<l>.?)[aeiou](?<r>.?)/) do 
     $~[:l] + (@@replace).call + $~[:r] 
    end 
    s 
    end 

    def callback(replace, match) 
    raise "Error: Match is empty" if match.nil? 
    return replace.upcase 
    end 
end 

t = Test.new 
puts t.transcribe('example') 

有人可以告訴我,如果我做錯了什麼,或者它是一個錯誤?

我用Google搜索了它:ruby Regexp.last_match lambda,並且在不同的情況下,似乎有一個$1的錯誤,但我不明白它是否與此相關。

回答

0

可以匹配作爲參數傳遞給塊

s.gsub!(/(?<l>.?)[aeiou](?<r>.?)/) do |match| 
    $~[:l] + (@@replace).call(match) + $~[:r] 
end 

這應該解決您的問題。

一般來說,我不會使用類似$~的魔術,除非它與正則表達式位於同一行。它使代碼更具可讀性。

1

正則表達式全局變量(Regexp.last_match只是$〜的一個訪問器)根本就不是全局的。從docslast_match

注意,last_match是局部的,做了 模式匹配方法的線程 和方法的範圍。

因此,當你的lambda被定義在一個不同的方法中時,方法範圍是不同的,所以它訪問它自己的專用Regexp.last_match,它沒有設置。最簡單的事情可能是通過Regexp.last_match作爲你的lambda的參數

相關問題