루비에서 변수가 nil이 아니고 0이 아닌지 확인


271

변수가 0이 아닌 0이 아닌지 확인하기 위해 다음 코드를 사용하고 있습니다.

if(discount != nil && discount != 0) 
  ...
end

더 좋은 방법이 있습니까?


1
아마도 stackoverflow.com/questions/209495/… 의 정확한 사본이기 때문일 것 입니다.
David Nehme

1
discount거짓 인 경우 어떻게해야 합니까?
Andrew Grimm

1
내 생각 discount.in? [0, nil]가능한 청소기 방법
intmarinoreturn0

답변:


428
discount.nil이 아니라면? || 할인 == 0
  # ...
종료

31
|| 대신 'or'를 사용하십시오.
Orion Edwards

93
@ orion-edwards 왜?
NARKOZ

39
'또는'을 사용하는 것은 위험합니다. 다음과 같은 예기치 않은 동작이 때문에 '또는', '='보다 낮은 운영자 presendence이있다 : a는 거짓 = 또는 사실 #A이 문 후 거짓
톰 G

20
@xiy는 현재 가이드에서 척하거나 또는 존재하지 않는 것을 권장합니다 (||는 && 및?)
user3125280

67
현재 "루비 스타일 가이드"는 의미 The and and or keywords are banned. It's just not worth it. Always use && and || instead.합니다. 그리고 다윗과 톰의 이유로 옳습니다.
Andre Figueiredo

40
class Object
  def nil_zero?
    self.nil? || self == 0
  end
end

# which lets you do
nil.nil_zero? # returns true
0.nil_zero?   # returns true
1.nil_zero?   # returns false
"a".nil_zero? # returns false

unless discount.nil_zero?
  # do stuff...
end

일반적인 면책 조항에주의하십시오 : 강력한 힘 / 책임, 어두운면으로 이어지는 원숭이 패치 등.


28

5 년이 지난 후 ....

if discount.try :nonzero?
  ...
end

이 노트에 중요 try그것이 일반 루비에서 사용할 수 없습니다 있도록 ActiveSupport 보석에 정의되어 있습니다.


7
이것은 레일 전용 답변입니다. 바닐라 루비에는 try방법 이 없습니다 .
Tom Lord

옳은. ActiveSupport 전용과 비슷하지만 전체 레일보다 훨씬 가볍고 널리 사용되는 종속성입니다. 어쨌든 @ndn의 응답이 옳습니다.
다시 작성

안전한 항해 사용하는 편집

1
대답은 이제 stackoverflow.com/a/34819818/1954610 ...을 복제 try합니다. 대체 옵션을 보여 주면 가치가 있다고 생각합니다 (이것이 처음에 upvoted 된 이유입니다!). ActiveSupport바닐라 루비가 아닌 독자 .
Tom Lord

포인트를 가져 와서 응답이 롤백되었습니다.
다시 작성

27
[nil, 0] .include? (할인)이 아닌 한 
  # ...
종료

13
아름다운? 예. 읽을 수 있습니까? 실제로는 아닙니다.
El Ninja Trepador 2016 년

1
나는 이것을 완벽하게 읽을 수 있으며 새로운 클래스보다 선호합니다. 잘 했어.
colincr

두 가지 조건을 처리하는 가장 루비 주의적 접근.
Yugendran

23

Ruby 2.3.0부터 안전한 탐색 연산자 ( &.) 와을 결합 할 수 있습니다 Numeric#nonzero?. 인스턴스가 있었고 -숫자 인 경우를 &.반환 nil합니다 .nilnonzero?0

if discount&.nonzero?
  # ...
end

또는 접미사 :

do_something if discount&.nonzero?

"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String.... 임의의 객체에는 사용하기에 안전하지 않습니다.
Tom Lord

2
이전 주석에서 언급했듯이 @TomLord는 임의의 객체와 작동하지 않습니다. 대신 숫자로 알고 있어야 할 수도 있지만 그럴 수도 있습니다 nil.
ndnenkov

누군가가 이것을 읽거나 주석에서 면책 조항을 발견하지 않고 대답에서 그 사실을 분명히 밝힐 것입니다.
Tom Lord

@TomLord, 그것은 " nonzero?- 숫자0"인 경우 답변에 명시되어 있습니다. 또한 완전히 임의의 객체가 있는지 확인해야 할 필요 0가있을 수도 있고 없을 수도있는 숫자를 확인하는 것과 비교할 때 극히 드물게 발생합니다 nil. 따라서 거의 암시됩니다. 누군가가 어떻게 든 반대되는 가정을하더라도, 실행하려고 할 때 무슨 일이 일어나고 있는지 즉시 이해할 것입니다.
ndnenkov


15

당신은 이것을 할 수 있습니다 :

if (!discount.nil? && !discount.zero?)

경우 때문에 순서는 여기에 중요 discount하다 nil, 다음은 없을 것이다 zero?방법을. 그러나 Ruby의 단락 평가는 discount.zero?if discount가 평가를 시도하지 못하게해야합니다 nil.


11

빈 행을 정수 값으로 변환하고 0을 확인할 수 있습니다.

"".to_i.zero? => true
nil.to_i.zero? => true

주의 : 0.1.to_i == 0
Simon B.

3
if discount and discount != 0
  ..
end

업데이트는 것입니다 false위해 할discount = false


2

NilClass제공된 #to_i메소드를 활용하면 nil값에 대해 0을 리턴 합니다.

unless discount.to_i.zero?
  # Code here
end

경우 discount분수 일 수있다, 당신이 사용할 수있는 #to_f제로로 반올림되는 수를 방지하기 위해, 대신.


이것은 @oivoodo의 답변과 동일하지 않습니까?
캐리 스월 랜드

임의의 개체에는 작동하지 않습니다 . "".to_i == "foo".to_i == "0".to_i == 0. 당신의 방법은 모든 종류의 의도하지 않은 유형의 강제를 만들 것입니다. 또한 NoMethodErrorif에 discount응답하지 않으면 실패 합니다 to_i.
Tom Lord

2
def is_nil_and_zero(data)
     data.blank? || data == 0 
end  

""를 전달하면 빈 값으로 false를 반환합니까? true를 반환합니다. data = false 빈 경우와 동일합니까? nil, false, empty 또는 공백 문자열에 대해 true를 반환합니다. 그래서 공백을 사용하는 것이 낫습니까? 빈 문자열을 피하는 방법.


1
blank?레일 전용 방법이며 바닐라 루비에서는 사용할 수 없습니다.
Tom Lord

당신이 올바른지!! 여기에 게시 된 "ror"태그와 관련이 있다고 생각했습니다. 내 실수. 바닐라 루비에서는 작동하지 않습니다.
Saroj

1

데이터베이스 레코드를 처리 할 때 마이그레이션 도우미를 사용하여 모든 빈 값을 0으로 초기화하고 싶습니다.

add_column :products, :price, :integer, default: 0

0

코드가 초기화되기 전에 시도하지 않고 사용하지 않는 한 할인을 0으로 초기화 할 수 있습니다. 그것은 내가 생각하는 하나의 수표를 제거 할 것이고, 나는 다른 것을 생각할 수 없습니다.



0

더 깨끗한 접근법을 선호합니다.

val.to_i.zero?

val.to_i를 반환 0하면 발은 A는 nil,

그런 다음 최종 값이 0 인지 확인하면 됩니다 .


-1

다른 해결책은 다음과 같이 구체화를 사용하는 것입니다.

module Nothingness
  refine Numeric do
    alias_method :nothing?, :zero?
  end

  refine NilClass do
    alias_method :nothing?, :nil?
  end
end

using Nothingness

if discount.nothing?
  # do something
end

-7

다음은 루비 코드에 충분하다고 생각합니다. 나는 이것과 원본의 차이점을 보여주는 단위 테스트를 작성할 수 없다고 생각합니다.

if discount != 0
end

8
truediscount가 인 경우 평가됩니다 nil.
Andrew Grimm
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.