13

私は Ruby を使い始めたばかりですが、個人的には、次のことは「最小の驚きの原則」に違反していると感じています。つまり、ドキュメントから引用すると、その uniq! 「自分自身から重複する要素を削除します。変更が行われない場合 (つまり、重複が見つからない場合) は nil を返します。」

私には完全に直感に反しているように思えますが、これを説明できる人はいますか? これは、以下に .uniq! を追加して 1 行のコードを記述できるのではなく、最初の行を終了するには、代わりに次の 2 行を記述する必要があります。

  hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/)
  hooks = hooks.uniq

それとも、もっと良い方法がありませんか?

編集:

ユニック 了解です!そのオペランドを変更します。これが問題をよりよく示したものです。

  hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/)
  puts hooks.length #50
  puts hooks.uniq!.length #undefined method `length' for nil:NilClass

私はそのようにユニークだと主張します!作品はそれを完全に無意味で役に立たないものにします。確かに私の場合、指摘したように、最初の行に .uniq を追加するだけです。ただし、同じプログラムの後半で、要素をループ内の別の配列にプッシュしています。次に、ループの下で、配列を「重複排除」したいのですが、あえて「hooks_tested.uniq!」とは書きません。nil を返す可能性があるためです。代わりにhooks_tested = hooks_tested.uniq と書く必要があります

実際、配列を返すメソッドを考案するときは、少なくとも常に nil ではなく空の配列を返す必要があるというのはよく知られた原則であるという点で、これは特にひどい誤機能であると私は主張します。

4

5 に答える 5

11

これは、uniq!変更selfして値を返す場合uniq!、元のオブジェクトで実際に変更が発生したかどうかを知ることができないためです。

var = %w(green green yellow)
if var.uniq!
  # the array contained duplicate entries
else
  # nothing changed
end

あなたのコードでは、単に書くことができます

hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/)
hooks.uniq!
# here hooks is already changed

おそらく最後のメソッドステートメントであるため、フックの値を返す必要がある場合は、次のようにします

def method
  hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/)
  hooks.uniq
end

もしくはそうでないか

def method
  hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/)
  hooks.uniq!
  hooks
end
于 2010-01-20T15:05:15.637 に答える
5

上の感嘆符uniq!は、新しい配列を返すのではなく、配列を変更することを示しています。これを行う必要があります:

hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/).uniq

またはこれ

hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/)
hooks.uniq!
puts hooks.length
于 2010-01-20T15:04:53.233 に答える
2

uniq最初の行の末尾に追加できます(最後に感嘆符はありません)。

または、どうしても使用したい場合はuniq!

(hooks = IO.read(wt_hooks_impl_file).scan(/wt_rt_00\w{2}/)).uniq!
于 2010-01-20T15:04:01.003 に答える