考虑到 Ruby 中的一切都是一个对象,我们可以打开 irb 并输入类似的内容4.class
并"Text".class
查看对象来自哪个类,为什么不if.class
给出unless.class
返回值?
3 回答
考虑到 Ruby 中的一切都是对象
这取决于您对“对象”和每个“事物”的定义。“对象”可以表示“可以被程序操作的实体”(从现在开始我将称之为对象),或者“作为对象系统成员的值”(从现在开始我将称之为Object
)。
在Ruby 中,程序可以操作的所有东西(即每个对象)也是一个Object
,即一个类的实例。这与 Java 不同,例如,原语可以由程序操作(即在这个词的意义上是对象),但不是Objects
. 在 Ruby 中,不存在这种区别:每个对象都是一个对象Object
,每个对象Object
也是一个对象。
但是,语言中有些东西不能被程序操作,也不是类的实例,即它们既不是object也不Object
是 s。例如,这些是方法、变量、语法、参数列表、参数列表、关键字。
注意:你可以使用 Ruby 的反射 API 给你一个代表方法或参数列表的对象,但那个对象只是一个代理,它不是真实的东西。
所以,当我们说“一切都是对象”时,我们真正的意思是“每个对象都是一个Object
”,即程序可以操作的一切都是对象系统的成员,或者换句话说,有在对象系统之外没有值(与 Java 中的原语不同)。我们并不是说该语言中存在的所有内容也可以在运行时由程序进行操作。
为什么不
if.class
给出unless.class
返回值
好吧,首先,即使是 if
一个对象,它们也不会像你认为的那样做:当你foo
在 Ruby 中说类似的话时,它的意思是“取消引用局部变量foo
”或“以隐式接收者的身份调用foo
方法self
并且没有参数列表”。所以,
if.class
要么给你局部变量引用的对象的类,要么给你方法返回if
的对象的类,但绝不会给你本身的类。if
if
但if
无论如何,控制流关键字不是对象(既不是对象也不是Object
),因为关键字和控制流在 Ruby 中不是对象。
在Matz 和 David Flanagan所著的 The Ruby Programming Language一书中,它在第 2 页上说:
每个值都是一个对象
请注意,它并没有说明所有内容,只说明了每个值。
因为它们是语言关键字而不是对象。通常,您可以分配给变量的所有内容都是对象。
从技术上讲是正确的:诸如unless
可能具有编译器/解释器使用的类的关键字(取决于实际实现),但是作为语言用户,您甚至没有任何远程实际用途,因此不是暴露给你。
1.9.2-p320 :019 > def meth
1.9.2-p320 :020?> 'meth'
1.9.2-p320 :021?> end
=> nil
1.9.2-p320 :022 >
如果您观察问号和缩进,当 IRB 检测到需要继续的内容时,它会缩进。
1.9.2-p320 :022 > if.class
1.9.2-p320 :023?> ...
1.9.2-p320 :028?> end
SyntaxError: (irb):22: syntax error, unexpected '.'
if.class
^
(irb):28: syntax error, unexpected keyword_end, expecting $end
1.9.2-p320 :045 > if.if
1.9.2-p320 :046?> end
SyntaxError: (irb):45: syntax error, unexpected '.'
if.if
^
1.9.2-p320 :060 > str = 'abc'
=> "abc"
1.9.2-p320 :061 > str.
1.9.2-p320 :062 > length
=> 3
1.9.2-p320 :063 >
1.9.2-p320 :083 > if
1.9.2-p320 :084 > str
1.9.2-p320 :085?> puts '>>>'
1.9.2-p320 :086?> end
>>>
=> nil
1.9.2-p320 :087 >
如您所见,IRB 不会立即回复,即使存在明显错误,例如向保留字发送消息。这 ?是它正在等待语句的其余部分的标志。