2010-11-24 20 views
9

así que estoy tratando de hacer algo como esto:recursividad en el rendimiento

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 

que calificó como:

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

¿Es posible hacer algo como esto? Sigo obteniendo ningún bloque dado (rendimiento) (LocalJumpError).

Incluso he intentado hacer algo un poco diferente:

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

pero no hubo suerte

Gracias.

+1

Interesante. En casi 6 años de hacer Ruby, nunca antes había visto esta pregunta, y ahora dos personas diferentes preguntan exactamente la misma pregunta desde (lo que parece) dos lados opuestos del mundo en solo 10 horas de otro: [ Problema con los bloques de Ruby] (http://StackOverflow.Com/q/4259652/) –

+0

Eso es interesante. Son preguntas similares, excepto que la mía tiene la función recursiva en el rendimiento – Matt

Respuesta

12

Sí, se puede tomar el bloque como un argumento de forma explícita:

def func(x, y, &block) 

fijas que se pueden ceder a ella con la palabra clave de rendimiento, pero también puede pasar que a medida que Recurse:

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

El & en ambos casos significa que el argumento block no es un argumento normal, sino que representa el bloque que se puede adjuntar a cualquier llamada al método Ruby.

+0

cool, ¿hay alguna manera de hacerlo sin pasar el bloque? ¿Sería más fácil hacer un ciclo, tal vez? Gracias. – Matt

2

Falta pasar el bloque en la llamada recursiva.
La llamada recursiva debe ser como la siguiente: -

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

Dado que se ha perdido para pasar el bloque de la llamada recursiva, cuando el código golpea: -

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

el método no func have block pasado como argumento, en la llamada recursiva, pero ruby ​​intenta llamar a un bloque inexistente y, por lo tanto, al error.