무엇입니까 !! 루비를 의미합니까?


134

!!루비에 무엇이 있는지 궁금합니다 .

답변:


161

아닙니다. 값을 부울로 변환하는 데 사용됩니다.

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

Ruby에 대한 유일한 잘못된 값은 niland false이므로 일반적으로 사용할 필요는 없으므로 일반적으로 해당 규칙을 적용하는 것이 가장 좋습니다.

그것을 다음과 같이 생각하십시오

!(!some_val)

합법적으로 사용되는 것 중 하나는 엄청난 양의 데이터가 반환되지 않도록하는 것입니다. 예를 들어 has_image?, 메소드 에서 3MB의 이미지 데이터를 리턴하지 않거나 메소드에서 전체 사용자 오브젝트를 리턴하지 않을 수 있습니다 logged_in?. 를 사용하면 !!이러한 객체를 단순 true/ 로 변환합니다 false.


8
이것을 사용하는 것은 나쁜 습관이 아닙니다. Double bang은 종종 술어 (?로 끝나는 메소드)에서 명시 적으로 부울 값을 리턴하는 데 사용됩니다.
Swanand

6
루비는 객체의 복사본이 아닌 참조를 반환하므로 Alex는 큰 객체를 반환하는 것에 대해 걱정할 필요가 없습니다.
DSimon

10
@DSimon, 때로는 디버깅하는 동안 값을 인쇄하거나 기록 할 때와 같이 큰 객체에 대해 걱정할 필요가 있습니다.
Wayne Conrad

.nil?대신에 대신에 반환 하지 !!않습니까? 차이가 있습니까?
ashes999

3
당신의 가치가 부울란 일 때 차이가 있습니다. !!true #=> truetrue.nil? #=> false
알렉스 웨인

31

그것은 돌려 true오른쪽에있는 객체가없는 경우 nil가 아닌 false, false이 경우 nil또는false

def logged_in?   
  !!@current_user
end

1
Restful_Auth에서 나온 것이 분명합니까?! : D
Cameron

14

!부울 상태 부정을 의미하고, 두 !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 문이나 삼항 연산자를 사용하는 것보다 더 빠른 방법처럼 보입니다. 그냥 반환 할 수 없기 때문에 title, 그것뿐만 아니라 가장 가까운 일을 할 수있다 ... 나는 가정
카슨 마이어스

6

이 관용구는 다른 프로그래밍 언어에도 존재합니다. C에는 내장 bool유형 이 없었 으므로 모든 부울은 int대신 표준 값 0또는 로 입력되었습니다 1. 이 예를 보자 (명확하게하기 위해 괄호가 추가됨) :

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

"not-not"구문은 0이 아닌 정수를 1표준 부울 true 값으로 변환합니다.

그러나 일반적 으로이 일반적이지 않은 관용구를 사용하는 것보다 합리적인 비교를하는 것이 훨씬 낫습니다.

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

아니면 그냥 (x). !! 0/1 중 하나를 가져와야 할 때 유용합니다. (x)를 고려하거나 고려하지 않을 수 있습니까? 1 : 0 선명합니다.
derobert

3

단독 또는 을 수행해야하는 경우에 유용합니다 . Matt Van Horn의 답변에서 약간 수정하여 복사 :

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

!!1 ^ !!true
=> false

두 변수가 모두 nil 또는 nil이 아닌지 확인하기 위해 사용했습니다.

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

3

"이중 음수"이지만 연습은 권장되지 않습니다. rubocop를 사용 하는 경우 Style/DoubleNegation위반 으로 해당 코드에 대해 불평하는 것을 볼 수 있습니다.

이론적 근거 상태 :

이것은 암시 적이며 일반적으로 중복되므로 피해야 !!something합니다.!something.nil?


1
하지만 ... !!false # => falsewhile!false.nil? # => true
Doug

@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.