Ruby:为什么这个 WHEN 语句不适用于两个条件?

Ruby: why this WHEN-statement doesn't work with two conditions?

我的 Ruby 代码中有一个 case 基本上尝试以几种方式匹配字符串并相应地对其执行不同的操作,有点像这样:

case inst
when Rx_inst1
  (some function)
when Rx_inst2
  (some other function)
end

效果很好(我没有发布正则表达式,因为它非常非常长而且效果很好)。但是,当我尝试实施以下修改时,即使 RegEx 匹配字符串,如果它包含子字符串也不会执行条件:

case inst
when Rx_inst1
  (some function)
when Rx_inst2 && !/dom\./
  (some other function)
end

Rx_inst2 在等于 Nm. Friese = Fryzyjczyk, koń fryzyjski 或它之前匹配的任何其他类型的字符串时停止匹配 inst

我得到了与 && /dom\./&& inst.include?('dom.') 完全相同的结果,根据其他答案,这是正确的语法。我做错了什么?

很明显,Rx_inst2 && !/dom\./ returns(由于短路评估)第二个操作数的值,即!/dom\/(前提是Rx_inst2确实是Regexp 因此是真实的)。您可能需要在 Rx_inst2 中修改此正则表达式,没有简短的答案。

或者,您可以稍微更改所有这些 case 表达式,如下所示:

case
when inst =~ Rx_inst1
  # (some function)
when inst =~ Rx_inst2 && !(inst =~ /dom\./)
  # (some other function)
end

但在我看来,它并不是特别优雅的形式。

好的,原来是我让它这样工作的:

when (!inst.include?('dom.') and Rx_inst2)

我仍然不明白为什么我必须做以下所有这三件事:

  1. 更改操作顺序
  2. 将整个表达式用括号括起来
  3. 显式调用第一个,隐式调用第二个
case inst
when Rx_inst1
  (some function)
when Rx_inst2 && !/dom\./
  (some other function)
end

case 转换成一堆 if/elsif/else 语句与 .=== 运算符 所以你的代码等同于

if Rx_inst1 === inst
  (some function)
elsif (Rx_inst2 && !/dom\./) === inst
  (some other function)
end

(Rx_inst2 && !/dom\./) === inst 是这样工作的:

  1. (Rx_inst2 && !/dom\./) 部分的计算结果为 !/dom\./(Rx_inst2 是正则表达式,不是 nil 或 false)
  2. !/dom\./ === inst 给你结果

所以 when Rx_inst2 && !/dom\./ 匹配只要 !/dom\./ === inst 匹配

@Darigazz 很好地解释了 case 的工作原理以及您的代码为何有问题。您可以通过以下几种方式编写案例陈述。

#1

case inst
when Rx_inst1
  m1  
when Rx_inst2
  m2 if inst.match? /dom\./
end
如果 m2 if inst.match? /dom\./ 中有 inst.match? /dom\./ #=> false,则返回

nil。根据要求,if 可能会替换为 unless

#2

case inst
when Rx_inst1
  m1  
when /(?=.*dom\.)#{Rx_inst2}/
  m2
end

其中 (?=.*dom\.) 正向预测 。例如,

Rx_inst2 = /Bubba|Trixie/
/(?=.*dom\.)#{Rx_inst2}/
   #=> /(?=.*dom\.)(?-mix:Bubba|Trixie)/

根据要求,(?=.*dom\.) 可能会被 负前瞻 (?!.*dom\.).

取代