案件陈述不正常

时间:2014-04-23 07:07:37

标签: ruby-on-rails ruby

我无法理解。以下示例中的测试1是什么?:

class Test1
  def request
    Test2.new.get_request(self.class)
  end
end

class Test2
  def get_request(klass)
    p klass # => Test1

    case klass
    when Test1
      p 'Test1 is class'
    when "Test1"
      p 'Test1 is string'
    when :Test1
      p 'Test1 is sybol'
    else
      p 'wtf is klass ????'
    end
  end
end

Test1.new.request
# Test1
# "wtf is klass ????"

(如果self.class更改为self,则有效) 但这种行为的解释是什么?

2 个答案:

答案 0 :(得分:2)

解释是,在CASE语句的情况下,检查的比较是===,如果它是==。如果有的话

p "GOT IT" if klass == Test1

它会起作用,在做什么

p "GOT IT" if klass === Test1

不会产生印刷品。

简而言之,通过使用===运算符比较when子句中的对象和case子句中的对象而不是==来进行比较,因此klass变量中的TEST1值与===不比较(case stmt)。

为此案例添加更多清晰度:

1.8.7 :074 > Test1.new.class == Test1
 => true 
1.8.7 :075 > Test1.new.class === Test1
 => false 

第二个是case / when语句

答案 1 :(得分:1)

在case表达式中,使用===运算符将when子句与case值进行比较。它相当于:

if Test1 === klass
  p 'Test1 is class'
elsif "Test1" === klass
  p 'Test1 is string'
elseif :Test1 === klass
  p 'Test1 is sybol'
else
  p 'wtf is klass ????'
end

它没有按照你想要的方式工作的原因是因为Class#===被实现来测试右操作数是否是类的实例。它的目的是使基于对象类的case表达式变得方便。但在这里它会失败,因为你并没有真正试图确定对象的类。由于Test1不是自身的实例 - 它是Class的一个实例 - 该测试产生错误。

我认为,如果你真的需要在案例表达式中测试类身份,那么你得到的最好就像when ->k{ k == Test1 },但它只是一种尴尬的语言案例。