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
