Take this example Ruby expression:
case
when 3 then "foo"
when 4 then "bar"
end
I was surprised to learn that this is not a syntax error. Instead, it evaluates to "foo"
!
Why? What are the syntax and evaluation rules being applied here?
答案 0 :(得分:3)
在case
表达式的这种形式中,将评估与词法第一then
子句相关联的when
子句,该子句计算为 truthy 值。< / p>
参见ISO Ruby Language Specification的§11.5.2.2.4语义的b)2)(粗体强调我的):
语义
案例表达式评估如下:
- a)[...]
- 湾步骤c)中短语“O is matching”的含义定义如下:
- [...]
- 如果 case-expression 是 case-expression-without-expression , O 匹配当且仅当< em> O 是一个真实的对象。
- c)采取以下步骤:
- 按照它们在程序文本中出现的顺序搜索 when-clause s ,以获取匹配的 when-clause ,如下所示:
- i)如果 when-argument 的 operator-expression-list 存在:
- I)对于每个 operator-expression ,对其进行评估并测试结果值是否匹配。
- II)如果找到匹配值,则不评估其他 operator-expression ,如果有的话。
- ii)如果未找到匹配值,并且 splatting-argument (见11.3.2)存在:
- I)按照11.3.2中的描述构建一个值列表。对于结果列表的每个元素,按照列表中的相同顺序,测试它是否匹配。
- II)如果找到匹配值,则不评估其他值(如果有)。
- iii)当且仅当在 when-argument 中找到匹配值时, when子句才被视为匹配。稍后 when-clauses (如果有)在这种情况下不会被测试。
- 如果其中一个 when-clause 匹配,请评估此的 then-clause 的复合语句当子句。 case-expression 的值是结果值。
- 如果 when-clause 没有匹配,并且有 else-clause ,则评估 compound-statement else-clause 的内容。 case-expression 的值是结果值。
- 否则, case-expression 的值为
nil
。
RDoc documentation虽然不太精确,但也指出真实性是条件被省略时的选择标准;和词法排序决定了when
条款的检查顺序(粗体强调我的):
case
case语句运算符。案例陈述由可选条件组成,它位于
case
的参数位置,以及零个或多个when
子句。 匹配条件的第一个when
子句(或评估为布尔值,如果条件为空)“wins”,并执行其代码节。 case语句的值是成功的when
子句的值,如果没有这样的子句,则为nil
。
答案 1 :(得分:1)
根据设计,没有要匹配的值的case
语句表现为if
语句。
实际上与写作相同:
if 3
'foo'
elsif 4
'bar'
end