如果一切都是Ruby中的一个对象,甚至数学运算符都是应用于对象的方法,当我写的时候:
puts "Hello world"
方法是 puts ,参数是“Hello world”,但对象是什么?
答案 0 :(得分:10)
要查找方法,您可以致电:
method(:puts)
#=> #<Method: Object(Kernel)#puts>
所以puts
是Kernel
中定义的方法,可供每个对象使用。
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) )
。
答案 1 :(得分:10)
如果一切都是Ruby中的对象,
这有点误导性的措辞。例如。语法不是对象,块不是对象,条件表达式不是对象。
更好的措辞是:“每个值都是一个对象”。
甚至数学运算符都是应用于对象的方法,当我写:
puts "Hello world"
方法是 puts ,参数是“Hello world”,但对象是什么?
涉及两个对象。我怀疑你真正要问的是“什么是接收器对象”。 (实际上,涉及的对象还有很多,但现在让我们关注接收器和参数。)
消息发送始终具有接收方对象,即您将消息发送到的对象。如果未明确写出接收器对象,则隐式假定它是self
(总是计算为“当前对象”的伪变量)。现在,问题是:这里有什么(或“谁”)self
?
顺便说一句,这是编写Ruby代码时应该问自己的 最重要的问题之一。无接收消息发送到self
,实例变量在self
中查找。您应该始终了解哪个对象self
正处于您编写代码的位置。
在这种特殊情况下,当您在Rubyists称之为顶级的位置编写代码时,self
是Rubyist调用main
的预定义对象。它实际上没有名称,并且没有默认引用,但是'main'
是它inspect
时返回的内容,或使用to_s
将其转换为字符串:< / p>
to_s
#=> 'main'
inspect
#=> 'main'
您已经正确识别的第二个对象:它是由字符串文字String
的评估产生的"Hello World"
对象。
但是,这里涉及的对象更多。例如,main
是Object
的实例,因此Object
也必须存在。 "Hello world"
是String
的实例,String
必须存在。 String
和Object
都是类,即作为Class
类实例的对象,因此Class
必须存在。 Object
的超类是BasicObject
。 Class
的超类是Module
。 Object
混合Kernel
(Module
类的实例)。 Kernel#puts
会返回nil
,这是NilClass
的一个实例。 Kernel#puts
只是一个帮助方法,可以通过调用IO#puts
委托给$stdout.puts
。
因此,除main
和"Hello world"
,至少外,还涉及以下对象:nil
,NilClass
,{{ 1}},String
,Class
,Module
,Object
,Kernel
,BasicObject
和IO
对象已分配给全局变量IO
,表示Ruby进程的标准输出流。
这12个对象直接且密切地参与了代码片段的执行。
实际上,即使是简单的Ruby程序,还有更多的对象:
$stdout
在我的系统上,这会打印一个约9780个对象的数字。现在,其中一些是由ruby --disable-gems --disable-did_you_mean -e 'p ObjectSpace.count_objects[:TOTAL]'
创建的Hash
以及ObjectSpace::count_objects
内的键和值(例如Hash
对象Symbol
),以及当然,通过尝试打印出结果来创建:TOTAL
。但是大约有大约35个对象的顺序,所以执行中仍然有近10000个对象,基本上是一个什么都不做的空程序。
答案 2 :(得分:1)
“Hello world” 是定义为文字常量的字符串对象,作为 puts 方法的参数
puts "Hello world"
实际上是一种简单的方法
puts myFoo
其中myFoo必须是有效对象...在您的情况下myFoo = "Hello world"