2012-01-06 3 views
1

Dans le code ci-dessous, je voudrais appeler la méthode de classe done de la classe qui comprend le module à l'intérieur self.hellométhodes de classe d'appel à partir d'un module qui est inclus par cette classe Ruby

Explication:

A::bonjour appellera Mod::hello sera donc B::ciao

Je voudrais être en mesure de détecter la « classe appelant » (A ou B) Mod::hello afin de pouvoir appeler le A::done ou B::done

module Mod 
def self.hello 
    puts "saying hello..." 
end 
end 

class A 
include Mod 

def self.bonjour 
    Mod::hello 
end 

def self.done 
    puts "fini" 
end 
end 

class B 
include Mod 

def self.ciao 
    Mod::hello 
end 

def self.done 
    puts "finitto" 
end 
end 

Répondre

3

Bien que (peut-être) pas aussi propre que la réponse de Niklas, il est encore facilement faisable, et l'OMI plus propre que le modèle d'utilisation indiqué dans l'OP qui repose sur le savoir quel module est mélangé.

(Je préfère ne pas avoir à passer un argument aux méthodes mixins comme celui-ci lorsque les autres moyens existent)

La sortie:.

pry(main)> A::bonjour 
saying hello... 
fini 
pry(main)> B::ciao 
saying hello... 
finitto 

Les tripes:

module Mod 
    module ClassMethods 
    def hello 
     puts "saying hello..." 
     done 
    end 
    end 

    def self.included(clazz) 
    clazz.extend ClassMethods 
    end 
end 

Les déclarations de classe modifiées, en supprimant la référence du module explicite:

class A 
    include Mod 

    def self.bonjour 
    hello 
    end 

    def self.done 
    puts "fini" 
    end 
end 

class B 
    include Mod 

    def self.ciao 
    hello 
    end 

    def self.done 
    puts "finitto" 
    end 
end 

Vous peut également fournir une implémentation par défaut de done:

module Mod 
    module ModMethods 
    def hello 
     puts "saying hello..." 
     done 
    end 

    def done 
     throw "Missing implementation of 'done'" 
    end 
    end 

    def self.included(clazz) 
    clazz.extend ModMethods 
    end 
end 

Comme un commentaire à ce poste souligne, si l'extrait dans l'OP est une représentation fidèle de l'usecase réelle, vous pouvez aussi bien utiliser extend (au lieu de include), laissant tout propre:

module Mod 
    def hello 
    puts "saying hello..." 
    done 
    end 

    def done 
    raise NotImplementError("Missing implementation of 'done'") 
    end 
end 

Et les classes à l'aide extend:

class A 
    extend Mod 

    def self.bonjour 
    hello 
    end 

    def self.done 
    puts "fini" 
    end 
end 
+1

utilisation étendre, en utilisant notamment et un ClasssMethods est un anti-modèle en général, surtout quand il n'y a pas "méthodes d'instance". –

+0

@ Monouïe Alors que je suis d'accord, j'essayais de suivre au moins une partie du schéma de l'OP. (De plus, je ne suis pas sûr que l'OP n'était pas seulement un exemple simplifié, mais je vais mettre à jour la réponse.) –

+0

Merci, @ Monouïe :-) Merci pour votre réponse Dave =) La réponse originale est très informationnel et le mis à jour est ce que je cherchais =) – Abdo

Questions connexes