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)
is
false
。因此
false&&obj.is_a?(ThingB)
is
false
除非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)
is
false
false&&obj.is_a?(ThingB)
is
false
除非falseis
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)
除非,否则布尔逻辑很难用
解析。如果
,您可以用
重写它:

  • 除非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
和德摩根定律,可能会更清楚。