0

以下のコードは、配列をループし、factor_listそれぞれに指定された変数が含まれているかどうかを確認します。その場合、それらを配列から削除し、それらを乗算して、変数に関して最終結果を合計します。すべての操作の後、因子を配列に追加して戻します。

temp_factor = nil
factor_list.each{|factor|
        if factor._variables.include?(variable)
            if temp_factor == nil
                temp_factor = factor
            else
                temp_factor = multiply(temp_factor, factor)
            end
            factor_list.delete(factor)
        end
    }
temp_factor = sumOut(temp_factor, variable)
factor_list << temp_factor

問題は、前のループで設定されていたとしても、すべての反復でtemp_factor常に発生することです。nil主な問題はアレイの削除によるものだと思ったので、テストのために削除を削除したところ、問題は解決しました(もちろん、アレイはゴミでいっぱいです)。したがって、私temp_factorはオブジェクトの浅いコピーであり、その参照オブジェクトは元のオブジェクトと一緒になくなったという結論に達しました。次に、マーシャル トリックを使用してディープ コピーを試みましたが、役に立ちませんでした。

問題を解決できなかったので、これですべてです。これらすべての神話の背後にあるメカニズムを特定するのを手伝ってくれる人はいますか?

問題を回避するためにコードを書き直すことについて、皆さんがとても良いアドバイスをくれて本当に助かりました! しかし、私はまだ上記の問題を引き起こしたのだろうかと思っていますか? そのちょっとした情報を知ることができればいいですね!

4

2 に答える 2

3

C++ と STL を使った大学時代は、「現在繰り返しているコレクションを決して変更してはならない」ということを教えてくれました。では、アイテムをその場で削除する代わりに、新しい配列を作成してみませんか?

temp_factor = nil
new_factors = factor_list.map do |factor|
  if factor._variables.include?(variable)
    if temp_factor == nil
      temp_factor = factor
    else
      temp_factor = multiply(temp_factor, factor)
    end
    nil
  else
    factor
  end
end.compact

temp_factor = sumOut(temp_factor, variable)
factor_list = new_factors + [temp_factor]
于 2012-10-24T21:46:22.750 に答える
2

あなたがコードで何を達成しようとしているのか本当によくわからないので、最終結果をどうしたいかとその理由についてもっと詳しく説明していただけると助かりますが、私が思うことに基づいて'やろうとしていますが、いくつかのステップに分割することで、より明確になると思います。

# first, split the array into an array that matches and one that doesn't
matched, factors = factor_list.partition { |f| f._variables.include? variable }

# then call multiply with each element of the matched list on the result of
# calling it on the previous elements
temp_factor = matched.reduce { |acc, f| multiply(acc, f) }

temp_factor = sumOut(temp_factor, variable)
factor_list = factors << temp_factor

また、頻繁に再割り当てされる非常に多くの一時変数を持つことも再考します。これは、いつでもそれらの値が何であるかを追跡することが非常に難しくなり、バグが非常に発生しやすくなるためです。

于 2012-10-24T22:05:31.733 に答える