3

誰かが私に以下のコードが何をしているのか説明できますか? beforeハッシュafterです。

def differences(before, after)
    before.diff(after).keys.sort.inject([]) do |diffs, k|
        diff = { :attribute => k, :before => before[k], :after => after[k] }
        diffs << diff; diffs
    end
end

ペーパートレイルの異なる宝石からです。

4

2 に答える 2

4

密集したコードであることは間違いありません。だから、あなたが言うようbeforeafter、パラメータとしてメソッドに渡されるハッシュ(のような?)オブジェクトです。呼び出すbefore.diff(after)と別のハッシュが返され、すぐに.keys呼び出されます。これにより、返されたハッシュ内のすべてのキーがdiff返されます。キーは配列として返され、すぐにソートされます。

次に、最も複雑で密度の高いビットに到達します。injectそのソートされたキーの配列を使用して、メソッドはメソッドの戻り値となる配列を作成します (ブロックdiffs内で呼び出されます) 。injectinject

その配列は、相違点の記録で構成されています。before.diff(after)各レコードはハッシュであり、戻り値からソートされたキーの配列から 1 つのキーを取得することによって構築されます。これらのハッシュには、比較対象の属性、前のハッシュでどのように見えるか、後のハッシュでどのように見えるかが格納されます。

簡単に言うと、このメソッドは 2 つのハッシュ間の違いを取得し、それらをハッシュの配列にまとめます。そのハッシュの配列は、メソッドの最終的な戻り値です。

:injectこれよりもはるかに単純である可能性があり、多くの場合は単純です。通常、1 つの操作を繰り返し適用し、結果をアキュムレータに格納することにより、値のコレクションを 1 つの結果に単純に減らすために使用されます。他の言語のinjectように知っているかもしれません。はRubyの のエイリアスです。のより簡単な例を次に示します。reducereduceinjectinject

[1,2,3,4].inject(0) do |sum, number|
  sum + number
end
# => 10

0 はアキュムレータ - 初期値です。ペア|sum, number|sumは、 がアキュムレータになりnumber、配列内の各数値が次々になります。inject0 に 1 を加算しsum、次のラウンドのために結果をsumに格納し、 に 2 を加算し、結果を にsum再度格納するなどです。アキュムレータの単一の最終値がsum戻り値になります。ここで 10. あなたの例で追加された複雑さは、アキュムレータがブロック内の値とは種類が異なることです。それはあまり一般的ではありませんが、悪いことでも偏ったことでもありません。(編集: Andrew Marshall は、おそらくそれは悪いことであると指摘しています。元の質問に対する彼のコメントを参照してください。また、@tokland は、injecthere は map の非常に複雑な代替手段にすぎないと指摘しています。悪いです。) の例については、質問へのコメントでリンクした記事を参照してくださいinject

編集: @tokland がいくつかのコメントで指摘しているように、コードには簡単なmap. その場合、はるかに簡単に読むことができます。

def differences(before, after)
  before.diff(after).keys.sort.map do |k|
    { :attribute => k, :before => before[k], :after => after[k] }
  end
end

コードが何をしているかを説明することに集中しすぎていました。単純化する方法すら考えていませんでした。

于 2012-06-21T00:42:19.893 に答える
1

基になるオブジェクトに応じて異なる前後のエントリを検出し、それらの違いのリストをより便利な形式で作成します。

before.diff(after)異なるエントリを見つけます。

keys.sort(違いのマップの) キーをソートされた順序で提供します

inject([])に似mapていますが、空の配列に初期化された差分で始まります。

ブロックは、diffこれらの違いごとに行 (ハッシュ) を作成し、それを に追加しdiffsます。

于 2012-06-20T23:31:11.350 に答える