2012-03-28 14 views
3

Wenn self ist der Standard-Empfänger in Ruby und Sie 'puts' in einer Instanz Methodendefinition aufrufen, ist eine Instanz des Objekts der Empfänger dieses Aufrufs?Ruby self und puts

z.

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 

Antwort

6

Absolut, das aktuelle Objekt ist hier der Empfänger des Methodenaufrufs. Der Grund, warum das funktioniert, ist, weil das Modul Kernel eine puts-Methode definiert und in Object gemischt ist, die die implizite Stammklasse jeder Ruby-Klasse ist. Beweis:

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 

Dieser druckt puts called from #<MyClass:0x00000002399d40>, so dass das MyClass Beispiel ist der Empfänger.

1

MyClass erbt stillschweigend von Object, das in Kernel mischt.

Kernel definiert Puts als:

$stdout.puts(obj, ...) 

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

Daher Sie Puts nennen, bewegt er sich auf sich selbst, und Kaskaden bis zu Kernel.

+0

Sehr guter Punkt. Was ist das Protokoll hier, sollte ich meine Antwort löschen und Ihre (wie es genauer ist) verlassen? –

+0

Eigentlich lag ich falsch. 'self.puts' unterscheidet sich von dem Aufruf der' puts' Methode für die aktuelle Klasse. Also war die erste Überarbeitung meiner Antwort, die im Grunde dasselbe wie deine war, richtig und deine auch. –

Verwandte Themen