ruby除非有多个条件
通用代码:ruby除非有多个条件,ruby,multiple-conditions,Ruby,Multiple Conditions,通用代码: class ThingA end class ThingB end class ThingC end 为了为上述类型设置条件检查,我使用了基本的“if!…”构造,它产生了预期的准确结果 示例代码if!…: obj = ThingA.new puts 'yes it is a ThingC' if !obj.is_a?(ThingA) && !obj.is_a?(ThingB) # works ok # stdout => nothing obj = Thin
class ThingA end
class ThingB end
class ThingC end
为了为上述类型设置条件检查,我使用了基本的“if!…”构造,它产生了预期的准确结果
示例代码if!…:
obj = ThingA.new
puts 'yes it is a ThingC' if !obj.is_a?(ThingA) && !obj.is_a?(ThingB) # works ok
# stdout => nothing
obj = ThingB.new
puts 'yes it is a ThingC' if !obj.is_a?(ThingA) && !obj.is_a?(ThingB) # works ok
# stdout => nothing
obj = ThingC.new
puts 'yes it is a ThingC' if !obj.is_a?(ThingA) && !obj.is_a?(ThingB) # works ok
# stdout => yes it is a ThingC
考虑到“除非”是基本的“如果!…”构造的更具描述性的替代,我使用“除非”实现了上述内容
样本代码,除非:
obj = ThingA.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB) # BUG
# stdout => yes it is a ThingC
obj = ThingB.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB) # BUG
# stdout => yes it is a ThingC
obj = ThingC.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB) # ???
# stdout => yes it is a ThingC
显然,“除非”版本无法产生相同的准确结果
基于这些简单而直接的结果,是否有人很难得出结论“除非准确,否则无法处理多个条件”这里的问题在于逻辑和或,当你否定一个逻辑函数时,等价的是opossite和操作符的优先级:修饰符前面的逻辑函数 德·摩根定律提供了一种将否定分布在不同区域的方法 析取和连接:
¬ ( a ∨ b ) ≡ ( ¬ a ∧ ¬ b ),
及
(a)∧ (b)≡ (a)∨ (b)
就你而言
(not(a)和not(b))然后你否定它=>not(a或b)
除非=>如果
irb(main):001:0>等级ThingA结束
B类结束
类ThingC结束
=>零
irb(主):002:0>=>零
irb(主):003:0>=>零
irb(主):004:0>obj=ThingA.new
放上“是的,它是一个东西”,除非对象是a?(ThingA)| |对象是a?(ThingB)
obj=新事物
放上“是的,它是一个东西”,除非对象是a?(ThingA)| |对象是a?(ThingB)
obj=新事物
放上“是的,它是一个东西”,除非对象是a?(ThingA)| |对象是a?(ThingB)
irb(主):005:0>=>零
irb(主):009:0>=>零
irb(主要):013:0>是的,这是一件事
=>零
我在这里没有看到任何错误。您得到的输出是合乎逻辑的。让我详细分析一下您的代码
obj = ThingA.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB) # BUG
obj.is_a?(ThingB)
isfalse
。因此false&&obj.is_a?(ThingB)
isfalse
除非false
为true
。所以它会打印出来
obj = ThingB.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB)
obj = ThingC.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB)
obj.is_a?(ThingA)
为假。false&&obj.is_a?(ThingB)
为false
除非false
为真
,否则它会打印出来
obj = ThingB.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB)
obj = ThingC.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB)
obj.is_a?(ThingA)
isfalse
false&&obj.is_a?(ThingB)
isfalse
除非falseistrue
。因此它会打印带有除非的逻辑。
obj = ThingB.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB)
obj = ThingC.new
puts 'yes it is a ThingC' unless obj.is_a?(ThingA) && obj.is_a?(ThingB)
除非,否则布尔逻辑很难用解析。如果
,您可以用重写它:
除非a | | b
相当于if!(a | | b)
,这相当于if!a&&b
除非a和&b
相当于if!(a和&b)
,这相当于if!a | | b
你的“臭虫”
obj.is_a?(ThingA)和&obj.is_a?(ThingB)
必须为false
,如果ThingA
和ThingB
是独立类
只有当一个类是另一个类的子类时,它才可能是true
。在这种情况下,您只需要检查obj
是否是子类实例:
obj.is_a?(ThingA)和&obj.is_a?(Object)
为真当且仅当obj
为ThingA
对象,因此您可以编写:
obj.is\u a?(ThingA)
选择
例如,您可能应该使用case
:
obj = ThingA.new
case obj
when ThingA
puts "yes, it is a ThingA"
when ThingB
puts "yes, it is a ThingB"
when ThingC
puts "yes, it is a ThingC"
else
puts "no, it is some other Object"
end
或
或
他们返回:
yes, it is a ThingA
yes, it is a Thing A B or C
yes, it is a ThingA
注意:由于我想发布的文本不能作为评论,我不得不将其作为答案分享
谢谢大家的宝贵回答和评论。现在,正如我已经提到的,我想设置一个“非此即彼”的过滤器。我选择了if!obj.is_a?(ThingA)和&!obj.is_a?(ThingB)
。它不仅有效,而且还清楚地传达了“非此即彼”的意图
现在问题来了,为什么我要从这个语句中删除所有的!
,用if
替换为excel
,并期望新版本产生相同的结果?答案在于我们中的一些人/大多数人最初是如何被介绍到excel
的“Ruby也可以执行除非测试,这与if测试完全相反……”和“将除非看作表示“if not”的另一种方式。”(Huw Collingbourne的《Ruby之书》中的直接引用:pg87),基本上是led(更像misled)我相信除非在任何情况下都可以用作如果!
的替代方案。这就是为什么我希望它在这里也能工作的原因
新年决议第1项:,除非
严格禁止任何涉及一种以上情况的活动
任何人仍然执著于解决的复合条件if!
问题,除非可以通过将整个参数包含在!()
中来实现。例如,上述问题可以作为除非来解决(!obj.is_a?(ThingA)和&!obj.is_a?(ThingB))
。仅以学术精神分享。不要对否决投票感到气馁。如果你从“开始,除非expr
相当于如果!(expr)
”,然后转到化合物expr
和德摩根定律,可能会更清楚。