2011-08-23 15 views
8

Attualmente sto sperimentando con Ruby e Rails e ho trovato alcune sezioni di tutorial e libri sulla metaprogrammazione. Molti menzionano che si tratta di un componente essenziale di Ruby, ma non entrano davvero nei dettagli. È come se la metaprogrammazione fosse l'ultima frontiera per i programmatori di Ruby. Provenendo da uno sfondo .NET, sto lottando per capire perché è presumibilmente così utile.Perché è importante conoscere metaprogramming e eigenclasses in Ruby?

  • Quali vantaggi si ottengono quando si utilizza metaprogramming?
  • Che cos'è un eigenclass e in che modo è diverso da un singleton?
  • In quali situazioni è comune utilizzare metaprogramming?
  • Quali implicazioni etiche ci sono in giro usando il codice per modificare il comportamento di un altro codice, in particolare il codice che non è il tuo?

risposta

16
  • Quali benefici si ottengono quando si utilizza metaprogrammazione?

    È possibile creare API più espressive che senza di esso (ad esempio ActiveRecord utilizza metaprogrammazione per definire metodi di accesso in base ai nomi delle colonne di una tabella, in modo da poter scrivere le cose come person.age invece di qualcosa di simile person.read_attribute("age"), dove person è un oggetto record attivo e la tabella people ha una colonna denominata age e è possibile ottenere alcune cose con un codice significativamente inferiore rispetto a quello che altrimenti farebbe.

  • Che cos'è un eigenclass e in che modo è diverso da un singleton?

    I termini "eigenclass" e "classe singleton" sono usati in modo intercambiabile nel contesto di ruby.

  • In quali situazioni è comune utilizzare metaprogramming?

    In situazioni in cui altrimenti si avrebbe molto codice della piastra della caldaia o durante la creazione di DSL.

    Esempio di utilizzo caso 1:

    Invece di scrivere qualcosa di codice caldaia-piatto come questo:

    class Foo 
        def bar 
        @bar 
        end 
    
        def bar=(b) 
        @bar = b 
        end 
    
        def baz 
        @baz 
        end 
    
        def baz=(b) 
        @baz = b 
        end 
    end 
    

    È possibile scrivere questo codice molto più breve con il metodo metaprogrammazione attr_accessor, che definisce automaticamente getter e metodi setter con i nomi in base agli argomenti che si danno:

    class Foo 
        attr_accessor :foo, :bar 
    end 
    

    Se attr_accessor non ALR Eady esiste nella libreria standard, è possibile definire da soli come questo (per darvi un'idea di ciò che metaprogrammazione in Ruby assomiglia):

    class Module 
        def attr_accessor(*variable_names) 
        variable_names.each do |variable_name| 
         define_method(variable_name) do 
         instance_variable_get("@#{ variable_name }") 
         end 
    
         define_method("#{ variable_name }=") do |value| 
         instance_variable_set("@#{ variable_name }", value) 
         end 
        end 
        end 
    

    fine

  • Quali implicazioni etiche ci sono circa utilizzando il codice di modificare il comportamento di un altro codice, in particolare il codice che non è il tuo?

    Nessuno.

+1

+1 Mi piace molto l'esempio di 'attr_accessor', in quanto mostra importanti vantaggi di forti capacità di metaprogrammazione: metaprogramming mantiene il linguaggio stesso semplice. 'attr_accessor' potrebbe facilmente essere un costrutto linguistico separato in un'altra lingua (correlati: proprietà in C#, ecc.). In Ruby, è semplicemente un altro metodo. –

+0

Buona risposta. Mentre è vero che la classe eigenclass e singleton significano la stessa cosa in Ruby, quest'ultima è ora il termine preferito, come indicato dall'esistenza dei metodi 'singleton_class',' singleton_methods' e 'define_singleton_method'. –

4

C'è un tempo e un luogo per metaprogrammazione. Penso che venga citato pesantemente nei libri Ruby perché alla gente piace mostrare quello che Ruby può fare che anche altri linguaggi non possono fare.

La metaprogrammazione è come non conoscere la parola giapponese "burger" o "zuppa di noodle", ma conoscere il giapponese per "questo si prega" ("kore o kudasai"), ed essere in grado di indicare l'elemento sul menu. Permette una maggiore flessibilità, ma è necessario più contesto per sapere esattamente cosa si sta facendo.

Se si sta creando ActiveRecord, che consente di eseguire find_by_foo, la metaprogrammazione ha senso.

Se si sta scrivendo una libreria di test di mutazione come zombie-chaser o un'applicazione di test di caratterizzazione che testa diverse implementazioni di Ruby, come ad esempio Small Eigen Collider, quindi la metaprogrammazione ha senso.

Tuttavia, se si sta scrivendo un'applicazione, in genere non si deve eseguire la metaprogrammazione, ma semplicemente la programmazione. Ad esempio, se stai usando instance_variable_set nella tua applicazione, è più un odore di codice che un'indicazione di quanto sei bravo.

Le domande correlate che potresti voler leggere sono https://stackoverflow.com/questions/1236191/what-will-i-learn-from-metaprogramming-ruby e Ruby metaprogramming online tutorial e Metaprogramming how much is too much?.

Consiglio davvero il libro "Metaprogramming Ruby", perché non ti insegna solo metaprogrammazione, ma come funziona Ruby.

+0

+1 per esempio giapponese. Semplicemente perfetto! – rubish

Problemi correlati