2012-03-28 3 views
3

Если self является приемником по умолчанию в рубине, и вы вызываете «puts» в определении метода экземпляра, является ли экземпляр объекта получателем этого вызова?Ruby self и puts

E.g.

class MyClass 
     attr_accessor :first_name, :last_name, :size 

     # initialize, etc (name = String, size = int) 

     def full_name 
     fn = first_name + " " + last_name 
     # so here, it is implicitly self.first_name, self.last_name 
     puts fn 
     # what happens here? puts is in the class IO, but myClass 
     # is not in its hierarchy (or is it?) 
     fn 
     end 
    end 

ответ

6

Абсолютно, текущий объект является получателем вызова метода здесь. Причина этого заключается в том, что модуль Kernel определяет метод puts и смешивается с Object, который является неявным корневым классом каждого класса Ruby. Доказательство:

class MyClass 
    def foo 
    puts "test" 
    end 
end 

module Kernel 
    # hook `puts` method to trace the receiver 
    alias_method :old_puts, :puts 
    def puts(*args) 
    p "puts called on %s" % self.inspect 
    old_puts(*args) 
    end 
end 

MyClass.new.foo 

Печатается puts called from #<MyClass:0x00000002399d40>, поэтому экземпляр MyClass является приемником.

1

MyClass незаметно наследует объект Object, который смешивается в ядре.

Ядро определяет путы как:

$stdout.puts(obj, ...) 

http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-puts

Таким образом, вы называете путы, она движется к себе, и каскады до ядра.

+0

Очень хорошая точка. Какой здесь протокол, следует ли удалить свой ответ и оставить свой (как это более точно)? –

+0

На самом деле я ошибся. 'self.puts' отличается от вызова метода puts в текущем классе. Итак, первая ревизия моего ответа, которая в основном говорила так же, как ваша, была правильной, а ваша тоже. –

Смежные вопросы