2010-11-24 4 views
9

Donc, je suis en train de faire quelque chose comme ceci:Recursion rendement

def func(x,y) 
    if x.length == 1 then 
     n = x.pop() 
     yield(n,y) 
    else 
     n = x.pop() 
     yield(n,func(x,y)) 
    end 
end 

appeler comme:

a = func([1,2,3,4,5],0) do |x,y| 
    x+y 
end 

Est-il possible de faire quelque chose comme ça? Je continue d'obtenir aucun bloc donné (rendement) (LocalJumpError).

J'ai même essayé de faire quelque chose d'un peu différent:

def func(x,y) 
    func(x,y) do |tail| 
     .. 
    end 
end 

mais pas de chance

Merci.

+1

Intéressant. En près de 6 ans à faire Ruby, je n'ai jamais vu cette question surgir avant, et maintenant la même question est posée par deux personnes différentes de (ce qui ressemble) deux côtés opposés du globe en seulement 10 heures de l'autre: [ Problème avec les blocs Ruby] (http://StackOverflow.Com/q/4259652/) –

+0

C'est intéressant. Ils sont des questions similaires, sauf le mien a la fonction récursive dans le rendement – Matt

Répondre

12

Oui, vous pouvez prendre le bloc comme argument explicitement:

def func(x, y, &block) 

Vous pouvez toujours céder avec le mot-clé yield, mais vous pouvez également passer comme vous RECURSE:

yield(n, func(x, y, &block)) 

Le & dans les deux cas signifie que l'argument block n'est pas un argument normal, mais représente le bloc qui peut être attaché à n'importe quel appel de méthode Ruby.

+0

cool, est-il un moyen de le faire sans passer le bloc? Serait-il plus facile de faire une boucle peut-être? Merci. – Matt

2

Il vous manque pour passer le bloc dans l'appel récursif.
L'appel récursif devrait être comme ci-dessous: -

yield(n,func(x,y)) { |x,y| x+y}) 

Puisque vous avez manqué de passer le bloc dans l'appel récursif, lorsque le frappe code: -

 if x.length == 1 then 
    n = x.pop() 
    yield(n,y) <<<< Here 

la méthode func ne le fait pas avoir un bloc passé en argument, dans l'appel récursif, mais ruby ​​essaie d'appeler un bloc inexistant et donc l'erreur.