2009-06-21 4 views
8

Stavo cercando di capire questo invito:Come funziona questo metodo deprecate?

deprecate :new_record?, :new? 

che utilizza questo metodo deprecate:

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 

io non capisco la metaprogrammazione che viene usata qui. Ma questo è solo un altro modo di fare l'aliasing del metodo new_record? - quindi, in effetti, new_record? è ancora disponibile ma emette un avviso quando lo si utilizza? Qualcuno vorrebbe spiegare come funziona?

risposta

10

ok, quindi quello che succede qui è che tutte le funzionalità di old_method sono state spostate in new_method dal programmatore. Per fare in modo che entrambi i nomi puntino alla stessa funzionalità ma si noti la deprecazione, il programmatore inserisce la riga deprecate. Questo fa sì che la stringa specificata nel file < -RUBY heredoc (http://en.wikipedia.org/wiki/Heredoc) venga interpretata come codice (valutato) a livello di classe. Le interpolazioni delle stringhe funzionano esattamente come fanno nelle normali stringhe di rubino.

Il codice è quindi qualcosa di simile (se dovessimo estendere la metaprogrammazione)

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 

Spero che abbia un senso

+0

Sì, grazie. Ciò ha senso. Solo una cosa ancora non capisco - questa sintassi: << - RUBY, __FILE__, __LINE__ + 1 Se "<< - RUBY" avvia l'heredoc, a cosa serve il resto? Questa parte: __FILE__, __LINE__ + 1 – Hola

+0

Se cambio la definizione da deprecate a: "alias_method: new_record ?,: new?", Avrà lo stesso effetto di quanto sopra, tranne che non riceverò l'avviso? – Hola

+0

al meglio delle mie conoscenze, sì. Le informazioni __FILE__ e __LINE__ sono argomenti di posizionamento opzionali per class_eval. Se mancavano e veniva sollevata un'eccezione, il backtrace includeva qualcosa come '(eval): 3 new_record?'. __FILE__ è il file sorgente corrente e __LINE__ è il numero di riga corrente, quindi in caso di errore, il backtrace indicherà dove è stata definita l'istruzione eval. –