3

x = yRubyではxがyと同じオブジェクトを参照することを忘れて、何度か噛まれてきました。私は、Rubyの用語でそれが意味する言語にあまりにも慣れていますx = y.dup。これを忘れてy、割り当ての右側で安全だと思ったときに、うっかり変更してしまいました。

特別な理由なしに単純な割り当てを避けることは理にかなっていることがわかりますx = yが、同じことが他の場所に潜んでいる可能性があります。

name = (person.last_name.blank? ? 'unknown' : person.last_name)

後で、name << title名前だけでなく、person.last_nameを実際に変更することになります。

これがあなたにも起こった場合、あなたはそれを避けることをどのように学びましたか?探すべき特定の危険信号やパターンはありますか?あなたはあなたがするそれぞれの割り当てを疑って見ますか?よく使います.dupか?Rubyの使用法が私にとって第二の性質になるかどうかはわかりませんので、役立つヒントを歓迎します。

4

4 に答える 4

5

これは、Ruby のような (本質的に命令型の) 言語では正統ではないように聞こえるかもしれませんが、私のアドバイスは次のとおりです。代わりに新しいものを作成します。多少のパフォーマンスは犠牲になりますが、より明確で、よりコンパクトで、よりモジュール化され、デバッグしやすいコードが得られます。

http://en.wikipedia.org/wiki/Functional_programming

したがって、あなたの例では、新しい名前で新しい文字列を作成するだけです:

complete_name = name + title
于 2011-03-26T15:32:37.027 に答える
1

toklandの答えへの追加:

関数型アプローチは不変性を主張します。つまり、既存のオブジェクトを変更するのではなく、元のオブジェクトを変更したい場合はいつでも別のオブジェクトを作成します。これは、Ruby がもたらすオブジェクト指向のパラダイム (オブジェクトは内部で状態を保持し、メソッドを呼び出すことで変更できます) にやや反するため、2 つのアプローチの間で少しバランスをとる必要があります (一方で、私たちは利益を得ます)。単一の言語で簡単にアクセスできる複数のパラダイムを持つことによって)。

というわけで、とりあえず覚えておきたいのは以下の3点です。

  1. Ruby での割り当てとは何かを学びましょう。オブジェクトに名前を付けるだけです。したがって、あなたが言うとき、あなたは「名前が付けられたものにy=x別の名前を付ける」と言っているだけです.yx
  2. name << title と呼ばれるオブジェクトを変異させnameます。
  3. name += titlenameとという名前のオブジェクトを取り、それらを別のtitleオブジェクトに連結し、その新しいオブジェクト name を割り当てます。何も変化しません。name
于 2011-03-26T19:12:46.150 に答える
0

私もそのような状況に遭遇し、バグが発生し、それを理解するのに半日かかりました. 私は本質的にこのようなことをしました

hash = {....}
filename = object.file_name
hash.each |k, v| {file_name.gsub!(k, v) if file_name.include? k}

このコードはループ内にあり、ループ内で、変数file_nameが再び元の値に設定されることを期待していました。しかし、私が実行していたので、object.file_name が変更されましたfile_name.gsub!。これを解決するには2つの方法があります。.gsub!呼び出しを に置き換えるか、file_name = file_name.gsubまたは実行しますfile_name = object.file_name.dup。私は 2 番目のオプションを選択しました。

!とを持つメソッドには注意する必要があると思います<<。これらは、特にこのような代入後に、元のオブジェクトを変更するためです。

于 2011-03-26T17:15:31.653 に答える
0

変数を変更すると定義されていない限り、メソッドは変数を変更してはなりません (例: シフト演算子を使用)。

したがって、(a) オブジェクトを作成したり、(b) オブジェクトを変更することを文書化したりしていないメソッドで、オブジェクトを変更しないでください。

于 2011-03-26T18:30:32.783 に答える