2012-07-30 1 views
0

J'ai toujours une crampe de cerveau quand il s'agit de cela. Je suis en train de créer un module à mélanger dans des classes semblables à des modèles, mais il doit conserver exactement une copie des attributs sérialisables par classe. Alors voici le code (ça ne marche pas).Ruby: Comment travailler avec classe Vars dans un module

module Checkin 
    module Model 
    def self.included(base) 
     base.extend(ClassMethods) 
    end 

    @@serialiable_attrs = [] <== really not the right place 
    module ClassMethods 
     def serializable(*attrs) 
     attrs.each{|attr| @@serializable_attrs << attr} # Is this @@ or just @? 
     end 
    end 

    def serialize! 
     @@serializable_attrs.each{|a| do_something_with(a)} # <== Will this work? 
    end 
    end 
end 

class Person 
    include Checkin::Model 
    serializable :first_name, :original_name, :last_name, :checked_in, :people_attending 
    # etc., etc. 
end 

Ce que je suis avec quereller sont deux choses:

  1. Comment définir mon mélange dans de telle sorte qu'une variable de classe naît comme par magie l'existence; et
  2. Comment accéder à cette variable à la fois dans mon module ClassMethods et dans la partie des méthodes d'instance (en l'absence d'un meilleur terme) du module.

Notez que je suis installé sur une technique de mélange en héritage plutôt que parce que je vais avoir Validatable, Persistable, Serializable et ainsi de suite. De plus, je sais qu'il existe toutes sortes de couches de validation et de persistance qui sont bien testées et très utilisées. C'est une bête différente et je devrais vraiment savoir qui faire ça dans mon sommeil, n'est-ce pas?

Tous les sorciers Ruby qui peuvent m'aider à comprendre comment faire cela ou suggérer une direction différente pour aborder ce problème, j'apprécie l'aide!

Répondre

1

Essayez de supprimer la variable de classe, et en ajoutant au module ClassMethod:

def self.extended(klass) 
    klass.instance_variable_set("@serializable_attrs", []) 
end 

Et changer le double @ à seule dans serializable. Et changer serialize! à ceci:

self.class.instance_variable_get("@serializable_attrs").each{|a| do_something_with(a)} 
+0

Merci! J'étais à mi-chemin quand je pensais, "c'est trop moche." Je suis content de voir que c'est juste mon imagination et que c'est juste. –

+0

@SteveRoss: Content de pouvoir aider. Juste travailler sur la valeur de «soi» dans votre tête. C'est la clé de la métaprogrammation de Ruby. Ruby n'effectue jamais de magie noire, souvenez-vous de cela. – Linuxios

Questions connexes