2011-01-18 21 views
13

Dado el siguiente método que toma un argumento:¿Es esto un error en el Método # to_proc? (1.8.7 rubí)

def foo(arg); p arg; end 

I puede llamar con una matriz vacía:

foo([]) 
# prints [] 

I también pueden guardar como un objeto Method y llamar que con una matriz vacía, con el mismo resultado:

method(:foo).call([]) 
# prints [] 

Sin embargo, si I c onvert el objeto Method a un Proc y llame que con una matriz vacía, consigo un ArgumentError:

method(:foo).to_proc.call([]) 
# ArgumentError: wrong number of arguments (0 for 1) 
# from (irb):4:in `foo' 
# from (irb):4:in `to_proc' 
# from (irb):10:in `call' 

esperaba que se comportan igual que los dos casos anteriores. En cambio, parece comportarse como si hubiera escrito foo(*[]). Sin embargo, si la llamo con una matriz -empty no, se hace comportarse de la manera que esperaba:

method(:foo).to_proc.call([1]) 
# prints [1] 

Así que desestructura el argumento, pero sólo si el argumento pasa a ser una matriz vacía. Y solo si llamo al Method#to_proc.

¿Hay alguna brecha en mi comprensión de cómo funcionan Method o Proc, o es esto un error?

Estoy ejecutando Ruby 1.8.7-p299. Observo el mismo comportamiento en 1.8.6-p399 y 1.8.7-head. Sin embargo, no lo veo en 1.9.1-p378: allí los tres formularios imprimen [] cuando se les llama con una matriz vacía.

+4

Normalmente soy escéptico cuando alguien piensa que ha encontrado un error en el lenguaje mismo, pero no veo otra explicación para este comportamiento, especialmente teniendo en cuenta que funciona como se esperaba en 1.9. Con suerte, alguien más sabio puede iluminarnos, porque esto me tiene bastante curioso. –

+1

No siempre encuentro un error en el idioma en sí, pero cuando lo hago, estoy usando Ruby. –

Respuesta

13

Esto es casi seguro que un error,

Sospecho que la razón de que esto está sucediendo es que el método # llamada tiene aridad -1 (Esperando una serie de argumentos C), y ProC# llamada tiene aridad -2 (Esperando una matriz de argumentos Ruby).

Hay un comentario más útiles en eval.c por encima de la definición de ProC# llamada que puede arrojar más luz sobre el tema:

/* CHECKME: la semántica mirando el argumento correcto? */

Tal vez deberíamos cambiar eso a un ARREGLAME: p

+4

Se corrigió en Ruby 1.9, así que creo que ERA un error :) – sethvargo

Cuestiones relacionadas