2011-09-10 28 views
0

我在写一些代码来评估一串字符串的存在,并且我想确保只有1个存在。它们是互斥的。寻找更好的与字符串逻辑异或解决方案

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?? Monkey patch字符串来定义一个运算符^?我只是习惯于能够做到if a,感觉不自然需要什么基本上是显式转换为布尔值。我觉得这个用例会在Ruby中“正常工作”。

回答

2

Enumerable实际上定义了一个one?方法,它完全符合你的需要。

# So either... 

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

# or 

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

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

不幸的是,如果你想two?或etcera,你运气不好。

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

如果你想检查是否准确的方法abc返回非空值之一,你可以使用:

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

甚至,由于数字,

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

这个问题没有明确说明,但我相信问题在于他正在寻找空字符串,表现得像是null(falsey)。 – numbers1311407

+0

我真的在寻找一个与字符串一起使用的逻辑异或运算符。我很好地把''“'算作真实的,因为它意味着客户端设置(或试图)。我在这个问题中使用了'present?',因为我知道''''''''变成'true'的唯一方法是使用'!!',但是会引发警告。 –

+0

Ruby中的字符串是真实的,不需要将它们转换为布尔值。唯一的falsey值是null(可能是用户没有设置属性时),并且为false。 –

相关问题