값이 nil인지 0인지 확인하는 간결한 방법을 찾고 있습니다. 현재 나는 다음과 같은 일을하고있다.
if (!val || val == 0)
# Is nil or zero
end
그러나 이것은 매우 서투른 것 같습니다.
답변:
객체에 nil이 있습니까? 방법 .
if val.nil? || val == 0
[do something]
end
또는 단 하나의 지침에 대해 :
[do something] if val.nil? || val == 0
or
여기에 괄호가 필요하지 않으며 숙련 된 Rubyist에게 완전히 자연스럽게 읽힐 것입니다. ||
대에 물린 유일한 사람은 or
Perl을 프로그래밍 한 적이없는 사람입니다. :)
val && val == 0
더 낫다고 생각 합니다.
끝에 물음표가있는 메서드 이름을 정말 좋아한다면 :
if val.nil? || val.zero?
# do stuff
end
귀하의 솔루션은 다른 몇 가지 솔루션과 마찬가지로 괜찮습니다.
루비는 조심하지 않으면 모든 것을 할 수있는 예쁜 방법을 찾게 만들 수 있습니다.
Ruby 2.3.0부터는 안전한 탐색 연산자 ( &.
)를 Numeric#nonzero?
. 인스턴스가 다음 과 같고-숫자가 다음 과 같으면 &.
반환 nil
합니다 .nil
nonzero?
0
unless val&.nonzero?
# Is nil or zero
end
또는 접미사 :
do_something unless val&.nonzero?
unless val&.nonzero?
"만약 발 IS 전무 제로"로 변환을
do_something if val&.nonzero?
(일명 경우 val
하지 nil
가 아닌 영).
먼저 그 특정 상태를 확인할 수있는 가장 간결한 방법이라고 생각합니다.
둘째, 이것은 디자인의 잠재적 인 결함을 나타내는 코드 냄새입니다. 일반적으로 nil과 0은 같은 것을 의미해서는 안됩니다. 가능하다면 메서드의 시작 부분이나 다른 메커니즘을 확인하여이 코드를 누르기 전에 val이 nil 일 가능성을 제거해야합니다.
이 경우 코드가 좋다고 생각하는 완벽하게 합법적 인 이유가있을 수 있지만 적어도 가능하면 nil 검사를 제거하는 것을 고려할 것입니다.
Object.nil을 사용할 수 있습니까? 구체적으로 nil을 테스트하기 위해 (그리고 false와 nil 사이에 걸리지 않습니다). 메서드를 Object에 몽키 패치 할 수도 있습니다.
class Object
def nil_or_zero?
return (self.nil? or self == 0)
end
end
my_object = MyClass.new
my_object.nil_or_zero?
==> false
Object에 대한 변경 사항은 동료가 추적하기 어렵고 다른 사람이 코드를 예측할 수 없게 만들 수 있으므로 권장되지 않습니다.
nil?
항상 false를 반환합니다. nil?
NilClass에서만 true를 반환합니다.
Object
, NilClass
및 에서 메서드를 구현할 수 Numeric
있습니다. Object
반환하고 false
, NilClass
반환 true
하고 Numeric
반환 zero?
합니다.
nil.to_i는 0을 반환하므로 자주 이렇게합니다.
val.to_i.zero?
그러나 val이 #to_i에 응답하지 않는 객체이면 예외가 발생합니다.
"5".to_i == 5, but you're more or less right. Clever but doesn't actually work
귀하의 코드가 잘못되었다고 생각합니다. : 그것은 사실 시험에서 세 가지 값에 대한 것 nil
, false
및 0. 이는 !val
루비에서 nil
및 인 거짓 인 모든 값에 대해 표현식이 참 이기 때문 false
입니다.
내가 지금 생각 해낼 수있는 최선의 방법은
if val == nil || val == 0
# do stuff
end
물론 영리하지는 않지만 (매우) 명확합니다.
내 솔루션은 조건을 제외한 구체화도 사용합니다.
module Nothingness
refine Numeric do
alias_method :nothing?, :zero?
end
refine NilClass do
alias_method :nothing?, :nil?
end
end
using Nothingness
if val.nothing?
# Do something
end
Rails는 속성 쿼리 메서드를 통해이를 수행합니다. 여기서 false 및 nil 외에도 0 및 ""도 false로 평가됩니다.
if (model.attribute?) # => false if attribute is 0 and model is an ActiveRecord::Base derivation
그러나 그것은 비방하는 사람들의 몫이 있습니다. http://www.joegrossberg.com/archives/002995.html
#attribute
. 왜냐하면 나는 그런 것을 찾을 수 없기 때문입니다.
가능한 한 관용적이기 위해 이것을 제안합니다.
if val.nil? or val == 0
# Do something
end
때문에:
짧고 명확
[0, nil].include?(val)
val.in? [0,nil]
가장 짧고 가장 좋은 방법은
if val&.>(0)
# do something
end
들어 val&.>(0)
이 때 발 IS 전무 이후 nil을 반환> 기본적으로 루비에서 false로 동일 전무, 또한 방법이다. 이 때 false를 돌려줍니다 val == 0
.
원하는 case
경우 사용할 수 있습니다 .
case val with nil, 0
# do stuff
end
그런 다음에서 작동하는 모든 것을 사용할 수 있습니다 ===
. 또는 다음과 같이하십시오.
not_valid = nil, 0
case val1 with *not_valid
# do stuff
end
#do other stuff
case val2 with *not_valid, false #Test for values that is nil, 0 or false
# do other other stuff
end
정확히 좋은 OOP는 아니지만 매우 유연하고 작동합니다. 어쨌든 내 if
s는 보통 s로 끝납니다 case
.
물론 Enum.any?
/ Enum.include?
종류의 작품도 ... 정말 비밀스러워지고 싶다면 :
if [0, nil].include? val
#do stuff
end
당연히 방법이나 기능을 정의하는 것이 옳은 일입니다. 또는 많은 값으로 동일한 작업을 수행해야하는 경우 이러한 멋진 반복기 조합을 사용하십시오.
원숭이가 클래스를 패치하는 대신 Ruby 2.1부터 개선을 사용할 수 있습니다 . 개선은 원숭이 패치와 유사합니다. 즉, 클래스를 수정할 수 있지만 수정은 사용하려는 범위로 제한됩니다.
이 검사를 한 번 수행하려면 과잉이지만 반복하는 경우 원숭이 패치에 대한 훌륭한 대안입니다.
module NilOrZero
refine Object do
def nil_or_zero?
nil? or zero?
end
end
end
using NilOrZero
class Car
def initialize(speed: 100)
puts speed.nil_or_zero?
end
end
car = Car.new # false
car = Car.new(speed: nil) # true
car = Car.new(speed: 0) # true
파일 범위를 지정하기 위해 마지막 순간에 수정 사항이 변경되었습니다 . 따라서 이전 예제에서 이것을 보여줄 수 있지만 작동하지 않습니다.
class Car
using NilOrZero
end
이것은 매우 간결합니다.
if (val || 0) == 0
# Is nil, false, or zero.
end
그것은만큼 당신이 치료 괜찮다로 작동 false
과 동일 nil
. 내가 작업 한 프로젝트에서 그 구별은 가끔 중요합니다. 나머지 시간에는 개인적으로 건너 뛰고 .nil?
코드가 약간 짧아지는 것을 선호 합니다.
[ 업데이트 : 더 이상 이런 건 쓰지 않아요. 작동하지만 너무 애매합니다. 내가 한 몇 군데를 바꿔서 내 잘못을 바로 잡으려고 노력했다.]
그건 그렇고, 예를 들어 문자열 .zero?
이면 예외 val
가 발생 하기 때문에 사용하지 않았습니다 . 그러나 .zero?
그것이 사실이 아니라는 것을 알고 있다면 괜찮을 것입니다.
[edited]
나는 만약 val
nil이면이 표현식이 다음 nil == 0
과 같이 평가 될 것이라고 생각했다 false
. 그러나 실제로는 작동하는 것처럼 보이지만 읽기가 쉽지는 않습니다.
또 다른 해결책 :
if val.to_i == 0
# do stuff
end
"5".to_i == 5
, 그러나 당신은 다소 옳습니다. 영리하지만 실제로 작동하지 않습니다.
val ||= 0
if val == 0
# do something here
end
val
유지해야하는 경우 어떻게 합니까? 이 방법으로 입력 데이터를 막고 있으며 nil 또는 0을 확인하는 더 좋고 덜 파괴적인 방법이 있습니다.
false
어떻게됩니까?