0

Ruby===在类型执行风格上使用运算符。case/when现在还知道 Ruby 根据when子句中存在的事物的类型,调用相应的.===方法。

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文字或任何有效的东西?

或者

  • .=== 在调用当前持有的事物上的相应操作员之前,它会执行什么测试when

编辑

在了解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)and时String.===("abc")。我认为我们发送的是not而是"abc"and 。10"abc".class10.class

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

现在看看上面。两者都返回true。它们是否true以相同的逻辑输出?我认为NO10.===(10)就像 10 ==(10)比较一样。但是作为类的Numeric.===(10)输出是 的子类。true10Numeric

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

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

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

我可能 100% 错了,在这种情况下,请纠正我。

4

2 回答 2

2

我将尝试解释@Lee Jarvis 也解释的内容。

class Someclass
end

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

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

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

所以 ruby​​ 没有做任何聪明的事,它只是向有问题的对象发送一条===消息(或者如果你愿意,也可以调用该===方法)。

于 2013-03-03T21:33:30.707 回答
1

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

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

不同的对象可能会以不同的方式做出反应。类检查参数是否是它们自己的实例,正则表达式检查参数是否被它们匹配,范围检查参数是否被它们覆盖。

这只是基本的方法调度。

于 2013-03-04T01:59:44.650 回答