2010-07-28 8 views
13

In welcher Art von Situation ist der Code:Ruby-Module und du selbst

module M 
    extend self 
    def greet 
    puts "hello" 
    end 

end 

günstiger über die Verwendung so etwas sagen wie:

module M 
    def self.greet 
    puts "hello" 
    end 
end 

In der Spitze, ein eine Instanzmethode Wesen erweitert, und letzteres ist nur eine Klassenmethode, aber wenn Sie eine Methode aufrufen, müssten Sie M.greet, richtig? Ich war nur neugierig, ob irgendjemand etwas Licht ins Dunkel bringen könnte, wenn man einen Code über dem anderen benutzen sollte. Vielen Dank!

Antwort

13

Das erste Beispiel ist in der Regel eine Art, wie Menschen, die Funktionalität von module_function erreichen (wenn sie nicht wissen, die Existenz diese Methode).

Ein module_function ist sowohl eine Instanzmethode als auch eine Klassenmethode. In Ihrem zweiten Codebeispiel ist die Methode nur eine Klassenmethode.

+0

Oh, das ist eine coole Methode. Auf diese Weise können Sie auswählen, auf welche Methoden Sie die Funktionalität anwenden möchten, wenn Sie sie nicht allen Benutzern zur Verfügung stellen möchten. Vielen Dank! – joeellis

9

Es wäre möglich, dies mit Ihrem ersten Beispiel zu tun, aber nicht Ihren zweite:

include M 
greet 
2

Ein Modul kann als Namespace verwendet werden, indem Modulmethoden geschrieben werden und die Instanzmethoden eines Moduls in ein anderes Objekt gemischt werden können.

Das selbstausdehnende Modulkonzept ermöglicht die Verwendung eines Moduls auf beide Arten; entweder als eigenständiger Namespace oder als Mixin. Betrachten Sie dieses Modul:

module M 
    def bar 
    puts "bar" 
    end 
end 
class C 
    include M 
end 

Es hat eine Instanzmethode und kann in ein anderes Objekt gemischt werden. Sie stellen keine Modul-Methode haben und kann daher nicht als Namespace verwendet werden:

puts M::bar # => undefined method `bar' for M:Module 
puts C.bar # => this is bar 

Aber ein Modul ist ein nur ein Objekt der Klasse Module, wie wir

puts M.class # => Module 

Diese Mittel nachweisen kann, dass wir etwas Verrücktes tun können. Wir können ein Modul in sich selbst mischen, so dass seine Methoden sowohl Instanz- als auch Modulmethoden werden.

module M 
    extend self 
    def bar 
    puts "bar" 
    end 
end 
puts M::bar # => this is bar 
puts C.bar # => this is bar