2015-04-17 15 views
8

In Ruby (e ancora di più: Rails) È easy to mark methods as deprecated.Come contrassegnare una classe come deprecata in Ruby?

ma come posso segnare un'intera classe come deprecato? Voglio sollevare un avviso ogni volta che si utilizza una classe:

class BillingMethod 
end 

BillingMethod.new #=> DEPRECATION WARNING: the class BillingMethod is deprecated. Use PaymentMethod instead. 

O quando viene utilizzato in eredità:

class Sofort < BillingMethod 
end 

Sofort.new #=> DEPRECATION WARNING: the class BillingMethod is deprecated. Use PaymentMethod instead. 

Oppure, se usato in classi nidificate:

class BillingMethod::Sofort < BillingMethod 
end 

BillingMethod::Sofort.new #=> DEPRECATION WARNING: the class BillingMethod is deprecated. Use PaymentMethod instead. 

I penseremmo che un blocco-class_eval sarebbe il posto in cui attaccare un tale avvertimento. È il posto giusto? O ci sono metodi migliori?

risposta

3

È possibile utilizzare const_missing deprecare costanti, e, per estensione, le classi.

const_missing sia invocata quando un costante indefinito viene fatto riferimento.

module MyModule 

    class PaymentMethod 
    # ... 
    end 

    def self.const_missing(const_name) 
    super unless const_name == :BillingMethod 
    warn "DEPRECATION WARNING: the class MyModule::BillingMethod is deprecated. Use MyModule::PaymentMethod instead." 
    PaymentMethod 
    end 
end 

In questo modo il codice esistente che fa riferimento a MyModule::BillingMethod di continuare a lavorare, e avvisa l'utente circa il loro uso della classe deprecato.

E 'il migliore che ho visto finora al fine di classe di disapprovazione.

+0

Nel tuo esempio, come si dovrebbe eseguire 'const_missing', quando lo hai definito appena sopra? – berkes

+0

@berkes la prima parte non dovrebbe essere lì, errore di battitura –

+0

Nel metodo 'const_missing', qual è la paymentmethod \' n FINE' esattamente ottenendo lì? – berkes

-2

perché non farlo in questo modo:

def initialize(*args) 
    warn "DEPRECATION WARNING: ..." 
    super 
end 
+0

Autore vuole mostrare avvertimento su tutti gli usi di classe (ad es. ereditarietà), non solo sulla creazione di nuovi oggetti. – hedgesky

8

Si consiglia di dare un'occhiata a Deprecate che fa parte della libreria standard di Ruby:

class BillingMethod 
    extend Gem::Deprecate 

    class << self 
    deprecate :new, "PaymentMethod.new", 2016, 4 
    end 

    # Will be removed April 2016, use `PaymentMethod.new` instead 
    def initialize 
    #... 
    end 
end 

Utilizzando il metodo deprecated si tradurrebbe in un avvertimento come questo:

BillingMethod.new 
# => NOTE: BillingMethod#new is deprecated; use PaymentMethod.new instead. It will be removed on or after 2016-04-01. 
# => BillingMethod#new called from file_name.rb:32. 
+0

Ciò solleverà solo gli avvisi quando un oggetto viene inizializzato. Non quando una classe viene utilizzata come genitore o utilizzata in un albero delle classi annidato. O mi manca un dettaglio importante? – berkes

+0

@berkes È possibile utilizzare quanto sopra per deprecare l'hook 'inherited' (metodo della classe), deprecando quindi l'ereditarietà:' class BillingMethod; classe << auto; deprecate: inherited,: none, 2016, 4; fine; FINE'. Ereditare da BillingMethod dovrebbe ora generare l'avviso di deprecazione. – PSkocik

+0

Il codice nell'esempio è errato. Poiché ': new' è un metodo di classe, è necessario racchiudere le righe' estendi ... deprecate' in un blocco 'class << self'. – berkes

Problemi correlati