2009-06-21 11 views
8

je tentais de comprendre cet appel:Comment fonctionne cette méthode deprecate?

deprecate :new_record?, :new? 

qui utilise cette méthode de Déprécier:

def deprecate(old_method, new_method) 
     class_eval <<-RUBY, __FILE__, __LINE__ + 1 
     def #{old_method}(*args, &block) 
      warn "\#{self.class}##{old_method} is deprecated," + 
       "use \#{self.class}##{new_method} instead" 
      send(#{new_method.inspect}, *args, &block) 
     end 
     RUBY 
    end 

Je ne comprends pas vraiment la métaprogrammation qui est utilisé ici. Mais, est-ce juste une autre façon d'aliaser la méthode new_record? - donc en effet, new_record? est toujours disponible mais il émet un avertissement quand vous l'utilisez? Quelqu'un voudrait-il expliquer comment cela fonctionne?

Répondre

10

ok, donc ce qui se passe ici est que toutes les fonctionnalités de old_method ont été déplacées à new_method par le programmeur. Pour que les deux noms pointent vers la même fonctionnalité mais notez la dépréciation, le programmeur place la ligne deprecate. Cela provoque l'interprétation de la chaîne spécifiée dans < -RUBY heredoc (http://en.wikipedia.org/wiki/Heredoc) en tant que code (évalué) au niveau de la classe. Les interpolations de chaînes fonctionnent exactement comme dans les chaînes ruby ​​normales.

Le code ressemble alors quelque chose comme ça (si nous devions étendre la métaprogrammation)

class SomeClass 
    def new?; true; end 

    deprecate :new_record?, :new? # this generates the following code 

    def new_record?(*args, &block) 
    warn "SomeClass#new_record? is deprecated," + 
      "use SomeClass#new? instead" 
    send(:new?, *args, &block) 
    end 
end 

J'espère que le bon sens

+0

Oui, merci. Ça a du sens. Juste une chose que je n'ai toujours pas - cette syntaxe: << - RUBY, __FILE__, __LINE__ + 1 Si "<< - RUBY" lance l'heredoc, à quoi sert le reste? Cette partie: __FILE__, __LINE__ + 1 – Hola

+0

Si je change la définition de deprecate en: "alias_method: new_record ?,: new?", Aura-t-elle le même effet que ci-dessus sauf que je ne recevrai pas l'avertissement? – Hola

+0

au meilleur de ma connaissance, oui. Les informations __FILE__ et __LINE__ sont des arguments de positionnement facultatifs pour class_eval. Si elles manquaient et qu'une exception était levée, le backtrace comprendrait quelque chose comme '(eval): 3 new_record?'. __FILE__ est le fichier source actuel et __LINE__ est le numéro de ligne en cours, donc en cas d'échec, le backtrace indiquera où l'instruction eval a été définie. –

Questions connexes