A. *_*her 7 ruby oop methods object puts
如果一切都是Ruby中的一个对象,甚至数学运算符都是应用于对象的方法,当我写:
puts "Hello world"
Run Code Online (Sandbox Code Playgroud)
方法是put,参数是"Hello world",但对象是什么?
Eri*_*nil 11
要查找方法,您可以调用:
method(:puts)
#=> #<Method: Object(Kernel)#puts>
Run Code Online (Sandbox Code Playgroud)
这puts是一个定义的方法Kernel,可用于每个Object.
puts "Hello world"
Run Code Online (Sandbox Code Playgroud)
实际上是
self.puts( String.new("Hello world") )
Run Code Online (Sandbox Code Playgroud)
self对象在哪里main.
所以puts "hello world"是:
main请注意,如果您执行
self.puts( String.new("Hello world") )
Run Code Online (Sandbox Code Playgroud)
你会收到一个错误:
private method `puts' called for main:Object (NoMethodError)
Run Code Online (Sandbox Code Playgroud)
因为每个内核方法都可用于每个Object,但作为私有方法.你需要:
self.send(:puts, String.new("Hello world") )
Run Code Online (Sandbox Code Playgroud)
另一种检查方法是:
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"
Run Code Online (Sandbox Code Playgroud)
它输出:
Calling Kernel#my_puts on main with ["Hello world"]
Now delegating to Kernel#puts on main with ["Hello world"] :
Hello world
Run Code Online (Sandbox Code Playgroud)
看到?一切都是一个对象,即使它可能看起来不像.
同样的道理:2+3实际上Integer(2).+( Integer(3) ).
Jör*_*tag 10
如果一切都是Ruby中的对象,
这有点误导性的措辞.例如,语法不是对象,块不是对象,条件表达式不是对象.
更好的措辞是:"每个价值 都是一个对象".
甚至数学运算符都是应用于对象的方法,当我写:
Run Code Online (Sandbox Code Playgroud)puts "Hello world"方法是put,参数是"Hello world",但对象是什么?
涉及两个对象.我怀疑你真正要问的是"什么是接收器对象".(实际上,还有更多的对象,但现在让我们关注接收器和参数.)
消息发送始终具有接收方对象,即您将消息发送到的对象.如果没有明确地写出接收器对象,则隐含地假定它是self(总是评估为"当前对象"的伪变量).现在,问题是:什么(或"谁")在self这里?
顺便说一下,这是编写Ruby代码时应该问自己的最重要的问题之一.无接收消息发送到self,查找实例变量self.您应始终了解self在编写代码时哪个对象.
在这种特殊情况下,当你写什么Ruby开发者调用代码顶级,self是一个预先定义的对象Ruby专家通话main.它实际上没有名称,并且没有对它的默认引用,但'main'它是它返回的inspect内容或使用to_s以下内容将其转换为字符串:
to_s
#=> 'main'
inspect
#=> 'main'
Run Code Online (Sandbox Code Playgroud)
您已经正确识别的第二个对象:它是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,String,Class,Module,Object,Kernel,BasicObject,IO,和IO分配给全局变量对象$stdout,代表你的Ruby进程的标准输出流.
这12个对象直接和密切地参与了代码片段的执行.
实际上,即使是简单的Ruby程序,还有更多的对象:
ruby --disable-gems --disable-did_you_mean -e 'p ObjectSpace.count_objects[:TOTAL]'
Run Code Online (Sandbox Code Playgroud)
在我的系统上,这会打印一个约9780个对象的数字.现在,其中一些是Hash由ObjectSpace::count_objects其中的键和值Hash(例如Symbol对象:TOTAL)String创建的,当然也是通过尝试打印出结果而创建的.但这大约是约35个对象的顺序,因此执行中仍然有近10000个对象,好吧,基本上是一个什么都不做的空程序.
“Hello world”是定义为文字常量的字符串对象,作为put方法的
puts "Hello world"实际上是一个简单的方法
puts myFoo
Run Code Online (Sandbox Code Playgroud)
其中 myFoo 必须是一个有效的对象......在你的情况下myFoo = "Hello world"