[英]What is the object in Ruby's “hello world”?
如果一切都是Ruby中的一个对象,甚至数学运算符都是应用于对象的方法,当我写:
puts "Hello world"
方法是put ,参数是“Hello world” ,但对象是什么?
要查找方法,您可以调用:
method(:puts)
#=> #<Method: Object(Kernel)#puts>
所以puts
是一个在Kernel
定义的方法,可用于每个Object。
puts "Hello world"
实际上是
self.puts( String.new("Hello world") )
self
是main
的对象。
所以puts "hello world"
是:
main
请注意,如果您执行
self.puts( String.new("Hello world") )
你会收到一个错误:
private method `puts' called for main:Object (NoMethodError)
因为每个内核方法都可用于每个Object,但作为私有方法。 你需要:
self.send(:puts, String.new("Hello world") )
另一种检查方法是:
module Kernel
def my_puts(*args)
print "Calling Kernel#my_puts on #{self} with #{args}\n"
print "Now delegating to Kernel#puts on #{self} with #{args} :\n"
puts(*args)
end
end
my_puts "Hello world"
它输出:
Calling Kernel#my_puts on main with ["Hello world"]
Now delegating to Kernel#puts on main with ["Hello world"] :
Hello world
看到? 一切都是一个对象,即使它可能看起来不像。
同样: 2+3
实际上是Integer(2).+( Integer(3) )
。
如果一切都是Ruby中的对象,
这有点误导性的措辞。 例如,语法不是对象,块不是对象,条件表达式不是对象。
更好的措辞是:“每个价值都是一个对象”。
甚至数学运算符都是应用于对象的方法,当我写:
puts "Hello world"
方法是put ,参数是“Hello world” ,但对象是什么?
涉及两个对象。 我怀疑你真正要问的是“什么是接收器对象”。 (实际上,还有更多的对象,但现在让我们关注接收器和参数。)
消息发送始终具有接收方对象 ,即您将消息发送到的对象。 如果没有明确地写出接收器对象,则隐式地假定它是self
(一直是评估“当前对象”的伪变量)。 现在,问题是:什么(或“谁”)是self
?
顺便说一下,这是编写Ruby代码时应该问自己的最重要的问题之一。 无接收消息发送给self
,实例变量在self
中查找。 您应始终了解在编写代码时哪个对象是self
。
在这种特殊情况下,当你在Rubyists称之为顶层的代码中编写代码时, self
是Rubyists称之为main
的预定义对象。 它实际上没有名称,并且没有默认引用,但是'main'
是它在inspect
它时返回的内容或使用to_s
将其转换为字符串:
to_s
#=> 'main'
inspect
#=> 'main'
您已经正确识别的第二个对象:它是由字符串文字"Hello World"
的评估产生的String
对象。
但是,这里涉及的对象更多。 例如, main
是Object
一个实例,因此Object
必须存在。 "Hello world"
是String
一个实例, String
必须存在。 String
和Object
都是类,即作为Class
类实例的对象,因此Class
必须存在。 Object
的超类是BasicObject
。 Class
的超类是Module
。 Object
混合在Kernel
(这是Module
类的一个实例)中。 Kernel#puts
返回nil
,这是NilClass
一个实例。 Kernel#puts
只是一个帮助方法,通过调用$stdout.puts
委托给IO#puts
。
因此,除了main
和"Hello world"
, 至少还涉及以下对象: nil
, NilClass
, String
, Class
, Module
, Object
, Kernel
, BasicObject
, IO
和分配给全局变量$stdout
的IO
对象,表示Ruby进程的标准输出流。
这12个对象直接和密切地参与了代码片段的执行。
实际上,即使是简单的Ruby程序,还有更多的对象:
ruby --disable-gems --disable-did_you_mean -e 'p ObjectSpace.count_objects[:TOTAL]'
在我的系统上,这会打印一个约9780个对象的数字。 现在,一些人的是Hash
通过创建ObjectSpace::count_objects
和里面的键和值Hash
(如Symbol
对象:TOTAL
),当然还有String
,试图打印出结果产生。 但这大约是约35个对象的顺序,因此执行中仍然有近10000个对象,好吧,基本上是一个什么都不做的空程序。
“Hello world”是字符串对象,定义为作为puts方法的参数给出的文字常量
puts "Hello world"
实际上是一个简单的方法
puts myFoo
其中myFoo必须是一个有效的对象...在你的情况下myFoo = "Hello world"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.