style standard rails guide coding code ruby coding-style

ruby - standard - rails style guide



Usando do block vs brackets{} (4)

En general, la convención es usar {} cuando se realiza una operación pequeña, por ejemplo, una llamada a un método o una comparación, etc. por lo que tiene perfecto sentido:

some_collection.each { |element| puts element }

Pero si tienes una lógica ligeramente compleja que va a varias líneas, utiliza do .. end como:

1.upto(10) do |x| add_some_num = x + rand(10) puts ''*'' * add_some_num end

Básicamente, todo se reduce a que, si su lógica de bloques va a varias líneas y no puede ajustarse en la misma línea, utilice do .. end y si su lógica de bloques es simple y solo una línea simple / única de código, utilice {} .

Nuevo en rubí, ponte tus guantes de novato.

¿Hay alguna diferencia (oscura o práctica) entre los siguientes dos fragmentos?

my_array = [:uno, :dos, :tres] my_array.each { |item| puts item } my_array = [:uno, :dos, :tres] my_array.each do |item| puts item end

Me doy cuenta de que la sintaxis del paréntesis le permitiría colocar el bloque en una línea

my_array.each { |item| puts item }

pero fuera de eso ¿hay alguna razón convincente para usar una sintaxis sobre la otra?


Esta es una pregunta un poco vieja, pero me gustaría intentar explicar un poco más sobre {} y do .. end

como se dijo antes

La sintaxis de paréntesis tiene un orden de precedencia más alto que el ... fin

pero cómo esto hace la diferencia:

method1 method2 do puts "hi" end

en este caso, se llamará do..end con el bloque de do ... do..end y do..end pasará al método 1 como un argumento! que es equivalente a method1(method2){ puts "hi" }

pero si dices

method1 method2{ puts "hi" }

luego se llamará al método2 con el bloque, luego el valor devuelto se pasará al método 1 como argumento. Lo cual es equivalente a method1(method2 do puts "hi" end)

def method1(var) puts "inside method1" puts "method1 arg = #{var}" if block_given? puts "Block passed to method1" yield "method1 block is running" else puts "No block passed to method1" end end def method2 puts"inside method2" if block_given? puts "Block passed to method2" return yield("method2 block is running") else puts "no block passed to method2" return "method2 returned without block" end end #### test #### method1 method2 do |x| puts x end method1 method2{ |x| puts x }

#### salida ####

#inside method2 #no block passed to method2 #inside method1 #method1 arg = method2 returned without block #Block passed to method1 #method1 block is running #inside method2 #Block passed to method2 #method2 block is running #inside method1 #method1 arg = #No block passed to method1


Hay dos estilos comunes para elegir do end vs. { } para bloques en Ruby:

El primer y muy común estilo fue popularizado por Ruby on Rails, y se basa en una regla simple de línea simple versus línea múltiple:

  • Utilice llaves { } para bloques de una sola línea
  • Use do end para bloques de varias líneas

Esto tiene sentido porque do / end lee mal en un solo liner, pero para bloques multilínea, dejar un cierre } colgando en su propia línea es inconsistente con todo lo demás que usa end en ruby, como definiciones de módulo, clase y método ( def etc.) y estructuras de control ( if , while , case , etc.)

El segundo estilo, menos visto con frecuencia, se conoce como semántica, o " Weirich Braces ", propuesto por el difunto y gran rubí Jim Weirich:

  • Use do end para bloques de procedimientos
  • Use llaves { } para bloques funcionales

Esto significa que cuando se evalúa el bloque para su valor de retorno , debe ser encadenable, y las {} llaves tienen más sentido para el encadenamiento de métodos.

Por otro lado, cuando el bloque es evaluado por sus efectos secundarios , entonces el valor de retorno no tiene ninguna consecuencia, y el bloque simplemente está "haciendo" algo, por lo que no tiene sentido estar encadenado.

Esta distinción en la sintaxis transmite un significado visual sobre la evaluación del bloque, y si debe preocuparse por su valor de retorno.

Por ejemplo, aquí el valor de retorno del bloque se aplica a cada elemento:

items.map { |i| i.upcase }

Sin embargo, aquí no está utilizando el valor de retorno del bloque. Está operando procedimentalmente, y tiene un efecto secundario con esto:

items.each do |item| puts item end

Otro beneficio del estilo semántico es que no necesita cambiar las llaves para hacer / finalizar simplemente porque se agregó una línea al bloque.

Como observación, casualmente , los bloques funcionales son frecuentemente de una sola línea, y los bloques de procedimiento (por ejemplo, config) son multilíneas. Por lo tanto, seguir el estilo de Weirich termina pareciéndose casi al estilo de Rails.


El libro de cocina de Ruby dice que la sintaxis de paréntesis tiene un orden de precedencia mayor que el ... do..end

Tenga en cuenta que la sintaxis del paréntesis tiene una precedencia más alta que la sintaxis do..end. Considere los siguientes dos fragmentos de código:

1.upto 3 do |x| puts x end 1.upto 3 { |x| puts x } # SyntaxError: compile error

El segundo ejemplo solo funciona cuando se usa paréntesis, 1.upto(3) { |x| puts x } 1.upto(3) { |x| puts x }