2013-10-14 13 views
19

Provare a utilizzare define_method all'interno di initialize ma ottenere undefined_method define_method. Che cosa sto facendo di sbagliato?Come utilizzare define_method all'interno initialize()

class C 
    def initialize(n)  
    define_method ("#{n}") { puts "some method #{n}" }  
    end 
end 

C.new("abc") #=> NoMethodError: undefined method `define_method' for #<C:0x2efae80> 
+0

Che cosa stai cercando di fare? –

+2

Niente di specifico, cercando di vedere come posso definire dinamicamente un metodo usando 'define_method' – Bala

risposta

20

Fate come di seguito:

class C 
    def initialize(n)  
    self.class.send(:define_method,n) { puts "some method #{n}" }  
    end 
end 

ob = C.new("abc") 
ob.abc 
# >> some method abc 

Module#define_method è un metodo privato e anche una classe method.Your uno non ha funzionato, come si è tentato di chiamare nell'istanza di C. Devi chiamarlo su C, usando #send nel tuo caso.

+1

Funziona. Potresti spiegare perché la mia versione precedente non è corretta? – Bala

+1

@Bala: nota che 'o = C.new ('pancakes')' ti lascerà con 'ob.abc',' ob.pancakes', 'o.abc', e' o.pancakes' come chiamate di metodo valide . Tutti sono sicuri che questo sia l'intento? –

+1

@muistooshort: commento interessante. Sebbene non ci fosse alcun intento, ora sto pensando a come renderlo oggetto specifico (singleton). – Bala

33

Ho il sospetto che stai cercando define_singleton_method:

define_singleton_method (simbolo, metodo) → NEW_METHOD
define_singleton_method (simbolo) {} blocco → proc

Definisce un Singleton metodo nel ricevitore. Il parametro metodo può essere un Proc, un Method o un oggetto UnboundMethod. Se viene specificato un blocco, viene utilizzato come corpo del metodo.

Se si utilizza define_method su self.class, si creerà il nuovo metodo come metodo di istanza su tutta la classe in modo che sarà disponibile come un metodo su tutte le istanze della classe.

usereste define_singleton_method come questo:

class C 
    def initialize(s)  
    define_singleton_method(s) { puts "some method #{s}" }  
    end 
end 

E poi:

a = C.new('a') 
b = C.new('b') 
a.a # puts 'some method a' 
a.b # NoMethodError 
b.a # NoMethodError 
b.b # puts 'some method b' 

Se il initialize fatto:

self.class.send(:define_method,n) { puts "some method #{n}" }  

allora si otterrebbe:

a.a # puts 'some method a' 
a.b # puts 'some method b' 
b.a # puts 'some method a' 
b.b # puts 'some method b' 

e probabilmente non è quello che stai cercando. Creare una nuova istanza e avere come conseguenza l'intera modifica della classe è piuttosto strano.

Problemi correlati