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 }