2010-06-26 64 views
1

我想明白下面的代碼是如何工作的:紅寶石 - 需要幫助理解這個注入

def url 
    @url ||= { 
    "basename" => self.basename, 
    "output_ext" => self.output_ext, 
    }.inject("/:basename/") { |result, token| 
    result.gsub(/:#{token.first}/, token.last) 
    }.gsub(/\/\//, "/") 
end 

我知道它做什麼;它以某種方式返回與位於服務器上目錄的文件相對應的url。所以它返回類似這樣的字符串:/path/to/my/file.html

據我所知,如果@url已經有一個值,它將被返回,並且正確的||=將被丟棄。我也明白,這開始創建兩個元素的散列。

我也覺得我明白了最後的gsub;它用反斜槓代替反斜槓(我想是爲了應付Windows服務器)。

令我驚訝的是inject部分。我無法理解它。我之前使用過inject,但這對我來說太過分了。我不明白each是如何實現的,因爲我不明白它的作用。

我對這個問題稍微修改了原始函數;原來來自this jekyll file

乾杯!

+3

「的最後一個gsub;它用斜線替換反斜槓「 - 不,它在我看來像是用斜槓替換雙斜線。 – Ken 2010-06-26 16:35:10

+0

你說得對 - 感謝你指出了這一點。 – kikito 2010-06-26 18:01:58

回答

2
foo.inject(bar) {|result, x| f(result,x) } 

總是可以寫爲:

result = bar 
foo.each {|x| result = f(result, x)} 
result 

所以對於你的情況,與每一個版本是這樣的:

result = "/:basename/" 
{ 
    "basename" => self.basename, 
    "output_ext" => self.output_ext, 
}.each {|token| 
    result = result.gsub(/:#{token.first}/, token.last) 
} 
result 

含義:所有鍵 - 值對在散列中,"/:basename/"中每個鍵的出現都被替換爲該值。

+0

哦。所以它基本上取代了'basename'的真實價值。我現在知道了。謝謝! – kikito 2010-06-26 16:27:33

1

也許分裂代碼和調整一點點幫助

options = { "basename" => self.basename, "output_ext" => self.output_ext } 

options.inject("/:basename") do |result, key_and_kalue| 
    # Iterating over the hash yields an array of two elements, which I called key_and_value 

    result.gsub(":#{key_and_value[0]}", key_and_value[1]) 
end.gsub!(//\/\/, '/') 

基本上,注入代碼遍歷所有的options和更換實際值只要它看到一個「:關鍵」