2016-07-07 5 views
2

Ich versuche, einige Methoden zu einer Klasse auf der Grundlage der Werte in seiner Reihenfolge Attribut zu offenbaren, die so etwas wie ['top', 'bottom', 'right', 'lower-right'] sein kann.Ruby: Metaprogrammierungsmethoden basierend auf Modellattribut

Zuerst meine Klasse löscht aus diesem Array etwas, das wie so leer reagiert:

def order 
    order.split(' ').delete_if do |o| 
    send(o).blank? if respond_to? o 
    end 
end 

Danach, ich will „aussetzen“ top (zum Beispiel willen) als eine Methode für die Klasse. Ich habe in der initialize Methode Sachen wie diese versucht:

order.each do |o| 
    V1_ATTRIBUTES << o.to_sym 
    define_method(o) do |a| 
    send(a).blank? ? '' : send(a) 
    end 
end 

Aber o ist nicht definiert, wenn die Klasse nicht instantialised ist, a la:

<NameError: undefined local variable or method `o' for #<Class:#<APIDocument:0x007fb8123609f8>>> 

Wer noch keinen Erfolg mit einer besseren Wie erreiche ich dieses Ergebnis?

Hinweis: Ich weiß, dass es nicht großartig ist, dem Benutzer zu ermöglichen, Instanzmethodennamen zu schreiben, aber in diesem Fall sind Sicherheit und Brüche kein Problem.

+0

Gibt es eine unendliche Rekursion bei der Implementierung der Methode 'order'? – Aetherus

+0

Nein, es wurde für diesen Beitrag vereinfacht. :) –

Antwort

2

Sie können Singleton-Methoden (pro Objektmethode) definieren.

def order 
    orders.split(' ').map{|o| send(o)}.compact.each do |o| 
    singleton_class.send(:define_method, o) do 
     send(o).to_s 
    end 
    end 
end 

Aber wie Sie sehen können, versagt dies nur Ihren Code. Also missbraucht Metaprogrammierung nicht, benutzt sie weise.

+0

Ah! Singleton-Methoden. Vielen Dank! –

Verwandte Themen