2012-03-17 17 views
6
class MyClass 
    def method_missing(name, *args) 
    name = name.to_s 
    10.times do 
     number = rand(100) 
    end 
    puts "#{number} and #{name}" 
    end 
end 

Ciao, sto esercitando rubino ma in questa funzione non ricorsiva sto ricevendo un errore di livello troppo profondo quando uso questo pezzo di codice.Livello di stack troppo profondo in Ruby

x = MyClass.New 
x.try 

risposta

11

Il problema con il codice è la variabile number definita all'interno times() cade su method_missing() portata. Pertanto, quando viene eseguita tale riga, Ruby lo interpreta come una chiamata di metodo su self.

In casi normali si dovrebbe ricevere l'eccezione NoMethodError. Tuttavia, poiché hai sostituito il metodo method_missing() per MyClass, non ottieni questa eccezione. Invece, viene chiamato il metodo overflow dello stack number(.

Per evitare tali problemi, provare a specificare i nomi dei metodi consentiti. Ad esempio, supponiamo che siano necessari solo i metodi try, test, and my_method da chiamare su MyClass, quindi specificare questi nomi di metodo su method_missing() per evitare tali problemi.

Per fare un esempio:

class MyClass 
    def method_missing(name, *args) 
    name = name.to_s 
    super unless ['try', 'test', 'my_method'].include? name 
    number = 0 
    10.times do 
     number = rand(100) 
    end 
    puts "#{number} and #{name}" 
    end 
end 

Se non si ha realmente bisogno method_missing(), evitare di utilizzarlo. Ci sono alcune buone alternative here.

+1

Sei 31 secondi più veloce di me. Ma immagino che 'puts" # {numero} e # {nome} "' si supponeva che fosse dentro il '10.times' ma forse no. –

+1

Eri solo più veloce di me! :) E non pensavo di aggiungere un po 'di super (big +1), ma per quanto riguarda il numero, penso che in realtà significhi qualcosa di più simile a 'number = Array.new (10) {rand (100)} .reduce (: +) ' – iain

+0

sì hai ragione. al momento non ha senso avere ore(), dal momento che puts non è all'interno del blocco :) –

Problemi correlati