繁体   English   中英

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

[英]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") )

selfmain的对象。

所以puts "hello world"是:

  • Kernel#puts方法调用
  • 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) )

如果一切都是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对象。

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

因此,除了main"Hello world"至少还涉及以下对象: nilNilClassStringClassModuleObjectKernelBasicObjectIO和分配给全局变量$stdoutIO对象,表示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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM