在调用' when '子句语句之前,Ruby对' when '子句执行什么测试?= = =”操作符



Ruby在case/when类型的执行风格上使用===操作符。现在它也知道Ruby取决于类型,则调用相应的.===方法。

假设when语句包含class名称,则规则为- it will use Module#===, which will return true if the right side is an instance of, or subclass of, the left side.

这里出现instance of测试

obj = 'hello'
#=> "hello"
case obj
when String
print 'It is a string'
when Fixnum
print 'It is a number'
else
print 'It is not a string'
end
#It is a string
#=> nil

此处出现subclass of测试

num = 10
#=> 10
case num
when Numeric
puts "Right class"
else
puts "Wrong class"
end
#Right class
#=> nil

现在when包含String字面值,然后调用String#=== =,这反过来检查是否在左侧和右侧字面量是否相同(相同序列中的相同字符)。

a = "abc"
#=> "abc"
case a
when "def" then p "Hi"
when "abc" then p "found"
else "not found"
end
#"found"
#=> "found"

所有的逻辑太酷了。现在我的查询是与case/when结构-

  • ruby如何知道when是否持有classString字量或在运行时有什么有效的吗?

  • 在调用相应的.===之前执行什么测试

编辑

在理解Case/when的工作原理之前,让我清除下面的when在轮到它时所做的事情。

String.===("abc") #=> true

因为"abc"是String类的实例。-我说的对吗?

现在我试着检查一下谁是谁的超类。

10.class #=> Fixnum
Fixnum.superclass #=> Integer
Integer.superclass #=> Numeric
Numeric.superclass #=> Object

嗯。这意味着下面的代码返回true,因为Fixnum也是Numeric的间接子类。-我说的对吗?

Numeric.===(10) #=> true

但是为什么下面的输出与上面的相反呢?

Numeric.===(Fixnum) #=> false

试图更具体到我的查询如下:

当我们调用Numeric.===(10)String.===("abc")。我认为我们发送的不是"abc"10,而是"abc".class10.class

10.===(10) #=> true
Numeric.===(10) #=> true

现在看看上面的内容。两者都返回true。它们在相同的逻辑上输出when0吗?我想是NO10.===(10)就像10 ==(10)比较。但是Numeric.===(10)输出true作为10的子类,CC_36是Numeric的子类。

"abc".===("abc") #=> true
String.===("abc") #=> true

现在看看上面的内容。两者都返回true。它们在相同的逻辑上输出true吗?我想是NO"abc".===("abc")就像简单的字符串文字比较"abc" ==("abc")比较。但是String.===("abc")输出true"abc", CC_45是String的一个实例。

现在我的问题是ruby如何检测左侧操作数类型并应用适当的比较规则?

我可能完全错了,那样的话,请纠正我。

我会试着解释@Lee Jarvis也解释过的东西。

class Someclass
end
s = Someclass.new
p s.methods.sort
#[:!, :!=, :!~, :<=>, :==, :===, :=~, :__id__, :__send__, :class, :clone,(...)

看第五种方法。我的Someclass实例有一个无处不在的===方法。

实际上,它有56个方法,我没有定义其中一个。它们继承自Object;Ruby中的每个类都继承自Object。对于类Object(和我的Someclass), #===实际上与调用#==相同,但是(正如文档所说)#===通常被后代覆盖,以便在case语句中提供有意义的语义。

所以ruby没有做任何聪明的事情,它只是发送一个===消息(或者调用===方法,如果你喜欢的话)。

现在我的问题是ruby如何检测左侧操作数类型并应用适当的比较规则?

它不。它只是调用===方法。就是这样。这就是面向对象的工作方式,并不是Ruby所特有的,所有 OO语言的工作方式都是一样的:在对象上调用方法,对象决定如何反应。(或者,在Ruby、PHP、Java、c#、c++、Python等基于类的语言中,对象的决定。)

不同的物体可能有不同的反应方式。类检查参数是否为自己的实例,regexp检查参数是否与它们匹配,范围检查参数是否被它们覆盖。

这只是基本的方法分派

最新更新