打印

Case << {case1, case2, case3, case4} && ===

本主题由 xavier 于 2008-3-21 19:30 解除置顶

Case << {case1, case2, case3, case4} && ===


前天在ruby mailing-list,用户Shai在写程序的时候出现一个问题:

下面是pseudo code:

 
case [a, b, c, d]
when x: 'nothing happens'
when y: 'nothing happens'
when z: 'nothing happens'
when a: 'render this option'
end


先回忆一下case syntax:

case object
when condition 1
  do something
when condition 2
  do something
  ...
end


n 久以前,c 和 pascal 定义 case function 的时候,被定义的 condition a 和 case b
的关系只有 perfect match (必须是 a==b).

由于广泛定义 regular expression 的原因,ruby的case做关系比较的时候和c与pascal不同,使用了 "===" (relationship operator === somewhat inappropriately === 关系符号 === 有逻辑关系的)
逻辑关系和对等关系是两个完全不同的概念, 大家对 "==" 已经非常熟悉,下面例子将大体阐述一下 "==="

#!/usr/bin/env ruby
#
#  Created by Yudi Xue on 2007-08-11.
#  Copyright (c) 2007. All rights reserved.

case "I am falling for her"
when /fall/
  puts "yes, You said fall"
else
  puts "there is no match..."
end

case /fall/
when "I am falling for her"
  puts "yes, you said fall"
else
  puts "there is no match..."
end


两个例子的结果截然不同,所以并不是所有时候:

=> case(a)?b == case(b)?a


回到上个例子,这段逻辑的意义是想将 a, b , c , d 四个 condition 存在 array 里进行分析
Shai主要希望将Array#include?和case两个function结合,他尝试如下做法:

case [3, 45, 6, 'abc'].inlcude?
when 1: 'no good'
when 3: 'good!'
when 'lolo': 'no good'
end

irb => not not enough arguments error


因为Array#include?必须输入参数进行比较 => [1,3,4].include?"1"

下面有人给出两个方案:

a = [1,2,3,4]
result = case
 when a.include?(1): 'this is what i want'
 when a.include?(11): 'not result'
 when a.include?(15): 'no good'
end




a = [1,2,3,4]
b = 2
result = case b
  when *a: "yes!"
  else "no!"
end


最终两个方法表现了相同的逻辑
相关 case 的解释可以参考 《The php?name=Ruby" onclick="tagshow(event)" class="t_tag">Ruby Way》英文版47页。


[ 本帖最后由 yudi 于 2007-8-11 16:39 编辑 ]

TOP

总结,===相当于include?方法

I.forget('you'){|something| something.remember.deepen}

TOP

这个说法适用于这里Array的案例
我想并不是所有的object都可以看作Array

TOP

恩,是有局限的,也适用用Range,但是思想上是通用的,也就是文中说“关系符号 === 有逻辑关系的”
===是Object的方法,在子类中被覆写了,以提供特定的功能。
也有比较值相等的时候:

a = '1'
b='1'
a===b
=>true




a=1
b='1'
b===a.to_s
=>true
a===b.to_i
=>true


也就是说,可以比较两个相同类型对象的值是否相等。。。

[ 本帖最后由 blackanger 于 2007-8-11 17:55 编辑 ]

I.forget('you'){|something| something.remember.deepen}

TOP

PR上说,在String里===和==是一样的

TOP

2008-12-02 10:42 Crawled by CCBot/1.0 (+http://www.commoncrawl.org/bot.html) @38.103.63.61