1

我想了解以下代码的工作原理:

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

我知道它的作用;它以某种方式返回与位于服务器上的 oa dir 的文件相对应的 url。所以它返回类似于这样的字符串:/path/to/my/file.html

我理解如果@url已经有一个值,它会被退回,权利||=会被丢弃。我也明白这开始创建两个元素的哈希。

我也认为我理解了最后一个 gsub;它用斜杠替换反斜杠(我猜是为了应对 Windows 服务器)。

令我惊讶的是这个inject部分。我无法理解它。我以前用过inject,但是这个对我来说太多了。我不明白如何用 来完成each,因为我不明白它的作用。

针对这个问题,我稍微修改了原函数;原件来自这个 jekyll 文件

干杯!

4

2 回答 2

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/"被替换为值。

于 2010-06-26T16:22:45.107 回答
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并在看到“:key”的任何地方替换实际值

于 2010-06-26T16:25:38.503 回答