Ruby的“hello world”中的对象是什么?

时间:2017-01-29 09:57:15

标签: ruby oop object methods puts

如果一切都是Ruby中的一个对象,甚至数学运算符都是应用于对象的方法,当我写的时候:

puts "Hello world"

方法是 puts ,参数是“Hello world”,但对象是什么?

3 个答案:

答案 0 :(得分:10)

要查找方法,您可以致电:

method(:puts)
#=> #<Method: Object(Kernel)#puts>

所以putsKernel中定义的方法,可供每个对象使用。

内核#放

puts "Hello world"

实际上是

self.puts( String.new("Hello world") )

其中self是对象main

所以puts "hello world"是:

  • Kernel#puts方法调用
  • on main
  • 以String对象作为参数。

注释

请注意,如果执行

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

同样: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"对象。

但是,这里涉及的对象更多。例如,mainObject的实例,因此Object也必须存在。 "Hello world"String的实例,String必须存在。 StringObject都是类,即作为Class类实例的对象,因此Class必须存在。 Object的超类是BasicObjectClass的超类是ModuleObject混合KernelModule类的实例)。 Kernel#puts会返回nil,这是NilClass的一个实例。 Kernel#puts只是一个帮助方法,可以通过调用IO#puts委托给$stdout.puts

因此,除main"Hello world"至少外,还涉及以下对象:nilNilClass,{{ 1}},StringClassModuleObjectKernelBasicObjectIO对象已分配给全局变量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"