Un detalle interesante (si, me quedo colgado con estupideces a veces
:)) es que a veces usar &block es más eficiente (en tiempo) que yield.

http://gist.github.com/4018d764d0538293eb96

El tema ahí es que por cada iteración la versión de each tiene que
llamar el bloque que pasa el usuario ({|i| list << i }), crear un
bloque nuevo ({|e| yield e }), y finalmente pasarle a Array#each ese
bloque.

La otra versión sólamente pasa el bloque que pasa el usuario ({|i|
list << i }) derecho a Array#each, sin intermediarios.

El tema de eficiencia va un poco porque la notación &block hace que
ruby castee el bloque tal como lo guarda en memoria a un objeto de
tipo Proc (que tiene más métodos, y es más pesado) para que el usuario
pueda manipularlo, pero en este caso, que lo único que queremos es
"forwardear" el bloque a otro método, es más eficiente ese casteo que
crear un bloque nuevo.

Habría que hacer un benchmarke de memoria, pero me embola hacerlo. Y
estoy casi seguro que en este caso, va a ser más eficiente en uso de
memoria la notación &block que el yield también, pero bue, queda como
ejercicio para el lector =P

El tema de la eficiencia en ruby no es repetir ciegamente lo que
alguien más dijo. Know thy implementation details.

-foca

PD: La charla de Evan en Locos x Rails me encantó, pero *la* crítica
que le hago (y que lo hablamos con varios de esta lista en LxR) es que
casi todo lo que dijo hay que tomarlo con un granito de sal, porque
depende un poco de qué estés haciendo.

Al que me diga que después de esa charla dejó de usar extend y usa
solo include—por ejemplo—voy a ir y le voy a extender el **** a
patadas porque no entendió nada =P

Ta, eso, tengo fiebre, me voy a dormir.
Capaz que tienen suerte, es gripe A, y me dejo de joderlos :-O :-P

2009/7/6 Nicolás Sanguinetti <[email protected]>:
> 2009/7/6 Cristhian Boujon <[email protected]>:
>> muchas gracias a todos, era evidente que algo no me estaba cerrando yo creí
>> que yield devolvía un valor al bloque pero también puede evaluarlo y todo
>> eso.
>> acá mi versión
>>
>> def select(array)
>>     otro_array = []
>>     array.each do |elem|
>>         otro_array << elem if yield(elem)
>>     end
>>     return otro_array
>> end
>>
>>
>> pero creo que es cierto lo que dice Eureliano, creo que se entiende mejor si
>> se usa el &block, lástima que sea más ineficiente y que casi ni se use.
>
> Ehhhhh "casi ni se use"? Es bastante común que se use esa notación, y
> hay casos donde no tenés más remedio que usarla. Para los casos
> simples (como sería implementar Enumerable#select, o #map, o ese tipo
> de cosas) es mejor usar yield (por la performance. Pero usar la
> notación &block tampoco es "inherently evil" ni nada.
>
> Otra cosa, la notación &block también ayuda a la documentación. Si hay
> un yield tirado en el medio del método, no hay nada que documente al
> leer el prototipo del método que ese método acepta un bloque.
>
> No hay una "silver bullet", a veces una notación es mejor que la otra.
> A veces es al revés.
>
> El que quiera "Only One True Way", que se vaya a programar en python :P
>
> -foca
>
_______________________________________________
Ruby mailing list
[email protected]
http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar

Responder a