2008-10-02 4 views
9

Imaginez le module Ruby suivant:Quel est le but des méthodes d'instance dans les modules sans classes?

module Foo 
    def inst_method 
    puts "Called Foo.inst_method" 
    end 
    def self.class_method 
    puts "Called Foo.class_method" 
    end 
end 

Il est évident que Foo.class_method peut être appelé sans instances de classe. Cependant, que se passe-t-il à Foo.inst_method? Est-il possible d'appeler Foo.inst_method sans inclure/étendre une classe? Clause de non-responsabilité: La question n'est pas centrée sur la résolution d'un problème réel. J'essaie juste d'améliorer ma compréhension du système d'objets Ruby.

Répondre

12

L'objectif principal des méthodes d'instance dans les modules est de donner cette fonctionnalité aux classes qui l'incluent. "Mélanger" dans un module de cette façon est le plus souvent utilisé comme une méthode de simulation multiple inheritance, ou dans d'autres situations où l'héritage n'est pas le bon paradigme (pas tout à fait une parfaite relation "est un") mais vous voulez partager comportement. C'est un outil de plus pour garder votre code DRY.

Un bon exemple de ce dans le noyau Ruby est de noter comment Array et Hash peuvent tous deux être parcouru et triés, etc. Ils reçoivent chacun cette fonctionnalité du module Enumerable (each_with_index, select, reject, sort et plus sont tous définis dans le module inclus, pas dans les classes).

4

Ma réponse serait: « Non, vous ne pouvez pas appeler des méthodes d'instance du module sans avoir d'abord l'extension ou comprenant ce module dans une classe »

maintenant connaître rubis et toute la ruse de programmation méta qu'il contient probablement là est une façon de l'appeler mais il serait en dehors de l'utilisation prévue des modules

module Tester 
    def inst_meth 
    puts "test inst meth\n" 
    end 

    def self.meth 
    puts "test self meth\n" 
    end 
end 

begin 
    Tester.meth 
rescue; 
    puts $! 
end 
begin 
    Tester.inst_meth 
rescue 
    puts $! 
end 
begin 
    Tester.new.inst_meth 
rescue 
    puts $! 
end 
begin 
    extend Tester 
    inst_meth 
rescue 
    puts $! 
end 
begin 
    include Tester 
    inst_meth 
rescue 
    puts $! 
end 

donne

>ruby test.rb 
test self meth 
undefined method `inst_meth' for Tester:Module 
undefined method `new' for Tester:Module 
test inst meth 
test inst meth 
Questions connexes