2017-10-13 8 views
1

En ruby, est-il possible d'obtenir une liste de tous les raffinements définis dans un module?Comment obtenir toutes les améliorations définies dans un module?

Par exemple, étant donné ceci:

module MyRefinements 
    refine String do 
    def foo 
     "#{self}_foo" 
    end 
    def trim 
     "this is not a good example, but demonstrates an override" 
    end 
    end 
end 

Comment puis-je obtenir un tableau comme celui-ci: [:foo, :trim]?

+0

voulez-vous l'obtenir à partir d'un analyseur de fichiers du module ou dans le code lui-même? – mabe02

+0

@ mabe02, je préférerais pouvoir l'obtenir à partir du code lui-même. –

Répondre

2

Mise à jour

Un peu laid, mais travailler. Vous devez connaître le nom du module et classe d'affiner la recherche:

module MyRefinements 
    refine String do 
    def foo 
     "#{self}_foo" 
    end 
    def to_str 
     "this is not a good example, but demonstrates an override" 
    end 
    end 
end 

# Provide module name and class (type) 
def get_refinements mod, type 
    ret = [] 
    mod.module_eval do 
    refine type do 
     ret = self.ancestors 
     .select{|el| el.to_s.include? "refinement" } 
     .map{|el| el.instance_methods(false)}.flatten 
    end 
    end 
    ret 
end 

module Test 
    p get_refinements(MyRefinements, String) 
end 

sortie est:

#=> [:to_str, :foo] 
+0

J'ai essayé de jouer avec votre idée. En fait, il semble être cohérent même lorsque vous affinez plus de types. Considéreriez-vous une bonne option pour fournir un hachage comme 'REFINED_METHODS = {}' où vous définissez le type comme clé et les méthodes affinées comme valeurs (ce que vous imprimez juste _flatten_) qui serait accessible comme 'MyRefinements :: REFINED_METHODS' ? – mabe02

+0

Est-il possible d'obtenir ceci de l'extérieur du bloc de raffinage? –

+1

Très bien! Je crois que vous pourriez simplifier un peu: 'refined_methods = []; MyRefinements.module_eval faire; affiner String do; refined_methods = instance_methods (false); fin; fin; refined_methods # => [: to_str,: foo] '. Si vous ajoutez la ligne 'puts 'self = # {self}, ancêtres = # {ancêtres}" ', elle afficherait' self = # 'et' ancestors = [# , String, Comparable, Object, Kernel, BasicObject] '. –