¿Es porque la do
de la sintaxis while
es sólo azúcar sintáctica y como nada que ver con el do
de un bloque?
Más o menos, sí. No es azúcar sintáctica, es simplemente un constructo de lenguaje incorporado, como def
o class
, como @meagar ya escribió.
No tiene nada que ver con el do
de un bloque, excepto que las palabras clave son caras y, por lo tanto, reutilizar palabras clave tiene sentido. (Por "cara" quiero decir que limitan el programador en su expresividad.)
En un bucle while
, hay dos maneras de separar el bloque de la condición:
- la palabra clave
do
y
- un separador de expresiones.
Hay, a su vez, dos diferentes separadores de expresión en Ruby:
- el punto y coma
;
y
- una nueva línea
Así, los tres de los siguientes son válidos:
while i = a.shift do puts i end # do
while i = a.shift; puts i end # semicolon
while i = a.shift
puts i end # newline
[Obvi ormente, esto último no estaría escrito de esa manera, que pondría la end
en una nueva línea, dedented para que coincida con el while
. Solo quería demostrar cuál es el mínimo necesario para separar las partes del lazo while
.]
Por cierto: es muy poco idiomático poner la condición entre paréntesis. También hay un montón de puntos y comas superfluos en tu código. Y el nombre de variable i
generalmente se reserva para un índice, no para un elemento. (Que normalmente utilizo el
de elementos genéricos, pero me gusta mucho más semánticas más nombres.)
También es altamente no-idiomática para recorrer una colección manualmente.El código sería mucho mejor escrito como
a.each(&method(:puts)).clear
No sólo es mucho más fácil de entender lo que esto (imprimir todos los elementos de la matriz y eliminar todos los elementos de ella), sino que también es mucho más fácil escribir (hay no es forma de obtener la condición de terminación incorrecta, o arruinar cualquier tarea). También resulta ser más eficiente: su versión es Θ (n), esta es Θ (n).
Y en realidad, tampoco es así como lo escribiría, porque Kernel#puts
ya implementa ese comportamiento. Por lo tanto, lo que haría muy escribir es este
puts a
a.clear
o tal vez esto
a.tap(&method(:puts)).clear
[Nota: este último no es 100% equivalente. Imprime una nueva línea para una matriz vacía, todas las demás imprimen nada.]
Simple. Claro. Conciso. Expresivo. Rápido.
Compare esto con:
while (i = a.shift) do; puts i ; end
que en realidad tenía que ejecutar varias veces para estar 100% claro lo que hace.
¡Gran pregunta! –