何が!! ルビーとは?


回答:


161

そうではありません。値をブール値に変換するために使用されます:

!!nil   #=> false
!!"abc" #=> true
!!false #=> false

ただし、Rubyへの唯一の偽の値はniland falseであるため、通常は使用する必要はありません。そのため、通常はこの規則を守ることが最善です。

それを次のように考える

!(!some_val)

正当に使用されていることの1つは、大量のデータが返されるのを防ぐことです。たとえば、has_image?メソッドで3MBの画像データを返したくない場合や、メソッドでユーザーオブジェクト全体を返したくない場合がありますlogged_in?。を使用!!すると、これらのオブジェクトが単純なtrue/に変換されますfalse


8
これを使用することは悪い習慣ではありません。ダブルバンは、述語(?で終わるメソッド)でよく使用され、明示的にブール値を返します。
スワンナン

6
アレックス、Rubyはオブジェクトのコピーではなく参照を返すので、大きなオブジェクトを返すことについて心配する必要はありません。
DSimon 2012

10
@DSimonでは、デバッグ中に値を出力したりログに記録したりする場合など、大きなオブジェクトについて心配する必要がある場合があります。
ウェインコンラッド

.nil?使用するのではなく、単に戻るのはなぜ!!ですか?違いはありますか?
ashes999

3
あなたの価値がブーリアンであるとき、違いがあります。!!true #=> trueおよびtrue.nil? #=> false
Alex Wayne

31

それは返しtrue、右上のオブジェクトでない場合nilとではないfalsefalseそれがある場合nilfalse

def logged_in?   
  !!@current_user
end

1
Restful_Authから来たのは明らかでしたか?!:D
キャメロン

14

!ブール状態を否定することを意味します。2つ!のsは、二重否定以外に特別なものではありません。

!true == false
# => true

通常、メソッドにブール値を返すように強制するために使用されます。文字列、整数など、あらゆる種類の真実性を検出し、ブール値に変換します。

!"wtf"
# => false

!!"wtf"
# => true

より実際的な使用例:

def title
  "I return a string."
end

def title_exists?
  !!title
end

これは、ブール値が確実に返されるようにする場合に役立ちます。私見それは一種の無意味ですが、両方if 'some string'if trueまったく同じフローであることがわかりますが、一部の人々は明示的にブール値を返すことが有用であると感じています。


if文や3項演算子を使用するよりも速い方法のように思えます。あなたはただ戻ることができないのでtitle、それに最も近いことをするのも良いかもしれません...おそらく
Carson Myers

6

このイディオムは他のプログラミング言語にも存在することに注意してください。Cには組み込みbool型がなかったため、すべてのブール値はint代わりに0またはの正規値で型付けされました1。この例を取り上げます(わかりやすくするために括弧を追加しています)。

!(1234) == 0
!(0) == 1
!(!(1234)) == 1

「not-not」構文は1、ゼロ以外の整数を正規のブール値trueに変換します。

ただし、一般的には、この一般的ではないイディオムを使用するよりも、妥当な比較を行う方がはるかに優れています。

int x = 1234;
if (!!x); // wtf mate
if (x != 0); // obvious

または(x)の場合のみ。!! 0/1を取得する必要がある場合に便利です。(x)を考慮してもしなくてもかまいません。1:0明確。
derobert 2009

3

排他的なorを行う必要がある場合に便利です。わずかな変更を加えたMatt Van Hornの回答からのコピー:

1 ^ true
TypeError: can't convert true into Integer

!!1 ^ !!true
=> false

2つの変数が両方ともnilであるか、両方ともnilではないことを確認するために使用しました。

raise "Inconsistency" if !!a ^ !!b

3

これは「ダブルネガティブ」ですが、この習慣は推奨されていません。rubocopを使用している場合は、Style/DoubleNegation違反のあるコードに対して文句が表示されます。

根拠の状態:

これは不可解な、通常は冗長でもあるとして、それは避けるべきである[その後、言い換え:]を変更!!somethingします!something.nil?


1
しかし... !!false # => falseしばらく!false.nil? # => true
ダグは

@Dougブール値があることがわかっている場合、それは冗長です(値を使用するだけです)。そうでない場合は、使用できます!(foo.nil? || foo == false)—より冗長ですが、不可解ではありません。
David Moles

0

たとえば、列挙型をブール値に変換する必要がある場合は、それがどのように機能するかを理解することが役立ちます。私はclassy_enumgem を使用してそれを正確に行うコードを持っています:

class LinkStatus < ClassyEnum::Base
  def !
    return true
  end
end

class LinkStatus::No < LinkStatus
end

class LinkStatus::Claimed < LinkStatus
  def !
    return false
  end
end

class LinkStatus::Confirmed < LinkStatus
  def !
    return false
  end
end

class LinkStatus::Denied < LinkStatus
end

それから私が持っているサービスコードでは、例えば:

raise Application::Error unless !!object.link_status   # => raises exception for "No" and "Denied" states.

事実上、bangbangオペレーターは、to_boolと呼ばれるメソッドとして筆者が作成したものになった。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.