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すでに値を持っている場合は、それが返され、権利||=が破棄されることを理解しています。また、これにより 2 つの要素のハッシュが作成されることも理解しています。

また、最後の 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 に答える