Tengo un compañero de trabajo que intenta convencerme activamente de que no debería usar do..end y, en cambio, usar llaves para definir bloques multilínea en Ruby.
Estoy firmemente en el campo de usar solo llaves para las frases cortas y terminar ... para todo lo demás. Pero pensé que llegaría a la comunidad en general para obtener alguna resolución.
Entonces, ¿cuál es y por qué? (Ejemplo de un código de hombro)
context do
setup { do_some_setup() }
should "do somthing" do
# some more code...
end
end
o
context {
setup { do_some_setup() }
should("do somthing") {
# some more code...
}
}
Personalmente, solo mirar lo anterior responde la pregunta para mí, pero quería abrir esto a la comunidad en general.
ruby-on-rails
ruby
ruby-on-rails-3
coding-style
Blake Taylor
fuente
fuente
Respuestas:
La convención general es usar do..end para bloques de varias líneas y llaves para bloques de una sola línea, pero también hay una diferencia entre los dos que se puede ilustrar con este ejemplo:
Esto significa que {} tiene una precedencia más alta que do..end, así que tenlo en cuenta al decidir qué quieres usar.
PD: Un ejemplo más a tener en cuenta mientras desarrollas tus preferencias.
El siguiente código:
realmente significa:
Y este código:
realmente significa:
Entonces, para obtener la definición real que desea, con llaves, debe hacer:
Tal vez el uso de llaves para los parámetros es algo que desea hacer de todos modos, pero si no lo hace, probablemente sea mejor usar do..end en estos casos para evitar esta confusión.
fuente
puts [1,2,3].map do |k| k+1; end
solo imprime el enumerador, es decir, una cosa? ¿No se pasan dos argumentos aquí, a saber,[1,2,3].map
ydo |k| k+1; end
?De la programación de Ruby :
Entonces el código
Vincula el bloque a la
param
variable mientras el códigoVincula el bloque a la función
f
.Sin embargo, esto no es un problema si incluye argumentos de función entre paréntesis.
fuente
Hay algunos puntos de vista sobre esto, es realmente una cuestión de preferencia personal. Muchos rubíes toman el enfoque que tú haces. Sin embargo, otros dos estilos que son comunes es usar siempre uno u otro, o usar
{}
para bloques que devuelven valores, ydo ... end
para bloques que se ejecutan para efectos secundarios.fuente
Hay un beneficio importante para las llaves: muchos editores tienen MUCHO más fácil hacer coincidirlas, lo que hace que ciertos tipos de depuración sean mucho más fáciles. Mientras tanto, la palabra clave "do ... end" es un poco más difícil de igualar, especialmente porque "end" también coincide con "if" s.
fuente
do ... end
palabras clave de forma predeterminadado ... end
es un caso especial que requiere una lógica específica del idioma.La regla más común que he visto (más recientemente en Eloquent Ruby ) es:
fuente
Estoy votando por hacer / terminar
La convención es
do .. end
para{ ... }
líneas múltiples y para líneas simples.Pero me gusta
do .. end
más, así que cuando tengo un forro único, lo uso dedo .. end
todos modos, pero lo formateo como de costumbre para hacer / terminar en tres líneas. Esto hace a todos felices.Uno de los problemas
{ }
es que es poesía en modo hostil (porque se unen estrechamente al último parámetro y no a toda la llamada al método, por lo que debe incluir métodos parensos) y, en mi opinión, simplemente no se ven tan bien. No son grupos de enunciados y chocan con constantes hash para facilitar la lectura.Además, he visto suficientes
{ }
programas en C. El camino de Ruby, como siempre, es mejor. Hay exactamente un tipo deif
bloque, y nunca tiene que volver atrás y convertir una declaración en una declaración compuesta.fuente
do_stuff if x==1
), que es un poco molesto convertir a la sintaxis regular. Pero esa es otra discusión.if
, postfixif
, postfixunless
(también una especie deif
, si no) y una líneaif
conthen
. La forma de Ruby es tener muchas maneras de expresar, de hecho, algo que siempre es lo mismo, mucho peor que lo que ofrece C que sigue reglas muy simples y estrictas.Un par de rubíes influyentes sugieren usar llaves cuando usa el valor de retorno, y hacer / finalizar cuando no lo hace.
http://talklikeaduck.denhaven2.com/2007/10/02/ruby-blocks-do-or-brace (en archive.org)
http://onestepback.org/index.cgi/Tech/Ruby/BraceVsDoEnd.rdoc (en archive.org)
Esto parece una buena práctica en general.
Modificaría este principio un poco para decir que debe evitar usar do / end en una sola línea porque es más difícil de leer.
Debe tener más cuidado al usar llaves, ya que se unirá al parámetro final de un método en lugar de la llamada completa al método. Simplemente agregue paréntesis para evitar eso.
fuente
En realidad, es una preferencia personal, pero dicho esto, durante los últimos 3 años de mis experiencias con el rubí, lo que he aprendido es que el rubí tiene su estilo.
Un ejemplo sería, si viene de un fondo JAVA, para un método booleano que podría usar
observe el caso del camello y, con mayor frecuencia, el prefijo 'es' para identificarlo como un método booleano.
Pero en el mundo rubí, el mismo método sería
así que personalmente creo que es mejor ir con 'ruby way' (pero sé que lleva un tiempo entenderlo (me llevó alrededor de 1 año: D)).
Finalmente iría con
bloques
fuente
Puse otra respuesta, aunque ya se señaló la gran diferencia (precedencia / encuadernación), y eso puede causar problemas difíciles de encontrar (el Hombre de hojalata y otros lo señalaron). Creo que mi ejemplo muestra el problema con un fragmento de código no tan habitual, incluso los programas experimentados no se leen como los domingos:
Luego hice un código de embellecimiento ...
si cambia
{}
aquído/end
obtendrá el error, ese métodotranslate
no existe ...Por qué sucede esto se señala aquí más de uno: precedencia. ¿Pero dónde poner llaves aquí? (@ The Tin Man: siempre uso llaves, como tú, pero aquí ... supervisado)
entonces cada respuesta como
es incorrecto si se usa sin el "PERO ¡Vigile los frenos / precedencia!"
de nuevo:
y
(cualquiera que sea el resultado de extender con el bloque ...)
Entonces, si desea usar do / end, use esto:
fuente
Se reduce a sesgo personal, prefiero las llaves en lugar de un bloque do / end, ya que es más comprensible para un mayor número de desarrolladores debido a que la mayoría de los lenguajes de fondo los usan en la convención do / end. Dicho esto, la clave real es llegar a un acuerdo dentro de su tienda, si do / end es utilizado por los desarrolladores del 6/10 que TODOS deberían usarlos, si el 6/10 usa llaves, entonces mantén ese paradigma.
Se trata de hacer un patrón para que el equipo en su conjunto pueda identificar las estructuras de código más rápido.
fuente
Hay una sutil diferencia entre ellos, pero {} se une más fuerte que do / end.
fuente
Mi estilo personal es hacer hincapié en la lectura más rígidas reglas de
{
...}
vsdo
...end
elección, cuando tal opción es posible. Mi idea de legibilidad es la siguiente:En sintaxis más compleja, como bloques anidados multilínea, trato de intercalar
{
...}
ydo
...end
delimitadores para obtener el resultado más natural, por ejemplo.Aunque la falta de reglas rígidas puede producir elecciones ligeramente diferentes para diferentes programadores, creo que la optimización caso por caso para la legibilidad, aunque subjetiva, es una ganancia neta sobre el cumplimiento de las reglas rígidas.
fuente
Ruby
era el mejor lenguaje pragmático que existe. Debería decir lenguaje de scripting. Hoy, creo que estarías igualmente bien aprendiendoBrainfuck
.Tomé un ejemplo de la respuesta más votada aquí. Decir,
Si verifica qué implementación interna en array.rb, el encabezado del método de mapa dice :
Invokes the given block once for each element of self.
es decir, acepta un bloque de código; todo lo que se encuentre entre do y end se ejecuta como rendimiento. Luego, el resultado se volverá a recopilar como matriz, por lo que devolverá un objeto completamente nuevo.
fuente
Hay una tercera opción: escribir un preprocesador para inferir "fin" en su propia línea, a partir de la sangría. Los pensadores profundos que prefieren un código conciso tienen razón.
Mejor aún, piratea Ruby para que sea una bandera
Por supuesto, la solución más simple de "elige tus peleas" es adoptar la convención de estilo de que una secuencia de extremos aparece en la misma línea, y enseñarle a colorear tu sintaxis para silenciarlos. Para facilitar la edición, uno podría usar scripts de editor para expandir / contraer estas secuencias.
Del 20% al 25% de mis líneas de código rubí son "fin" en su propia línea, todo inferido trivialmente por mis convenciones de sangría. Ruby es el lenguaje similar al lisp que ha logrado el mayor éxito. Cuando la gente discute esto, preguntando dónde están todos los paréntesis espantosos, les muestro una función de rubí que termina en siete líneas de "final" superfluo.
Codifiqué durante años usando un preprocesador lisp para inferir la mayoría de los paréntesis: una barra '|' abrió un grupo que se cerró automáticamente al final de la línea, y un signo de dólar '$' sirvió como marcador de posición vacío donde, de lo contrario, no habría símbolos para ayudar a inferir las agrupaciones. Esto es, por supuesto, territorio de guerra religiosa. Lisp / esquema sin paréntesis es el más poético de todos los idiomas. Aún así, es más fácil simplemente silenciar los paréntesis usando el color de sintaxis.
Todavía codifico con un preprocesador para Haskell, para agregar heredocs y para predeterminar todas las líneas de vaciado como comentarios, todo sangrado como código. No me gustan los caracteres de comentarios, sea cual sea el idioma.
fuente