2011-09-10 7 views
0

문자열 묶음의 존재를 평가하기위한 코드를 작성 중이고, 그 중 하나만 존재하도록하고 싶습니다. 그것들은 상호 배타적입니다.문자열로 더 나은 논리 XOR 솔루션을 찾고 있습니다.

class MyClass 
    include ActiveModel::Validations 
    attr_accessor :a, :b, :c 
    validate :mutex_values 

    def initialize(attr = {}) 
    attr.each do |k, v| 
     send("#{k}=", v) 
    end 
    end 

    private 
    def mutex_values 
    # here, I want to do this: 
    # errors.add(:base, "specify only 1") unless a^b^c 
    # instead I do this 
    errors.add(:base, "specify only 1") unless a.present?^b.present?^c.present? 
    end 
end 
MyClass.new(:a => "A", :b => "B", :c => "C").valid? 
=> false 

.present?을 반복적으로 사용해야하는 다른 방법이 있습니까? 원숭이 패치 연산자를 정의하는 문자열 ^? 난 그냥 할 수있는 데 익숙해 져있어 기본적으로 불리언에 대한 명시 적 형변환을 필요로하는 것은 부자연 스럽다고 느낀다고 if a. Ruby에서이 유즈 케이스가 '효과가있을 것'이라고 생각합니다.

답변

2

Enumerable은 실제로 정확히 당신이 필요로하는 것을 수행하는 one? 메서드를 정의합니다. . 당신이 two? 또는 etcera하려면

# So either... 

[a, b, c].one?(&:present?) 

# or 

[a, b, c].one?(&:presence) 

# ... would do the trick in this case. 

불행하게도, 당신은 운입니다.

2

당신은 count과 같은 것을 할 수 있습니다 :

errors.add(:base 'specify exactly 1') unless [a, b, c].count(&:present?) == 1 

당신이 다음 가장 한 대신 정확히 하나에 원하는 경우 : 예를 들어

errors.add(:base 'specify at most 1') unless [a, b, c].count(&:present?) > 1 

:

> ['',nil,'6',''].count(&:present?) 
=> 1 
> ['',nil,'6',11].count(&:present?) 
=> 2 
> ['',nil,''].count(&:present?) 
=> 0 
1

정확히 방법 a, bc 반환 null이 아닌 값 중 하나가, 당신이 사용할 수 있는지 여부를 확인하려면 다음

[a, b, c].compact.count == 1 

하거나, 감사 번호를

[a, b, c].one? 
+0

이 질문에 명시 적으로 언급되지는 않았지만 문제는 그가 null (허위) 인 것처럼 동작하는 빈 문자열을 찾고 있다는 것입니다. – numbers1311407

+0

문자열과 함께 사용할 논리 XOR 연산자를 찾고 있습니다. 나는 클라이언트가 클라이언트를 설정했거나 시도했음을 의미하기 때문에 사실로 간주한다. 왜냐하면 내가''사실 '로 바꾸는 유일한 방법은'!!'과 함께 있었지만 경고를 유발했기 때문입니다. –

+0

문자열은 Ruby에서 진리입니다. 문자열을 부울로 변환 할 필요가 없습니다. 잘못된 값은 null입니다 (사용자가 속성을 설정하지 않은 경우). false입니다. –

관련 문제