2016-09-27 31 views
3

Ich lerne Ruby und habe kürzlich etwas entdeckt, das ich nicht ganz verstanden habe. Beim Einmischen von Modulen in Klassen kann ein Klassenobjekt nicht auf die Modulinstanzmethoden zugreifen.Warum haben Klassenobjekte im Kernelmodul Zugriff auf Instanzmodule?

module Swimmable 
    def swim 
    puts 'can swim' 
    end 
end 

class Fish 
    include Swimmable 
end 

Fish.swim 

Ergebnis ist die undefined method 'swim' for Fish:Class (NoMethodError)

jedoch Verfahren, wenn die Instanz erwartet wird, in dem Kernel-Modul definiert ist, ich es mit einem Klassenobjekt und ein Instanz-Objekt zugreifen kann.

module Kernel 
    def swim 
    puts 'can swim' 
    end 
end 

class Fish; end 

Fish.swim # => can swim 
Fish.new.swim # => can swim 

Was die Objektklasse macht Fish können Instanzmethoden im Kernel-Modul zugreifen?

+0

Wenn Sie 'Swimmable' für Ihr Klassenobjekt verfügbar haben möchten, schreiben Sie 'extend Swimmable' in' Fish'. Auf diese Weise müssen Sie das Modul nicht in 'Kernel' definieren. Weiterführender Suchbegriff: _singleton class_ –

Antwort

1

Von the documentation:

Die Kernel-Modul von der Object-Klasse enthalten ist, so sind seine Methoden in jedem Ruby-Objekt zur Verfügung.

Beide Fish Instanzen und die Fish Klasse selbst sind Objekte, so dass sie alle Methoden in Kernel definiert haben.

Im ersten Fall erhalten Sie den Fehler, weil einschließlich Swimmable in FishSwimmable Mitglieder auf Instanzen von Fish, aber nicht auf die Klasse selbst zur Verfügung stellen.

+0

Danke für die Erklärung, es gab mir nur eine tiefere Ebene des Verständnisses 'Class' und' Object'. Grundsätzlich ist jede Instanzmethode im Klassenobjekt für jedes Klassenobjekt und Instanzobjekt verfügbar. –