2009-02-10 5 views
30

¿Qué estilo se prefiere? ¿Hay una buena razón para una frente a la otra?¿Cuál es la diferencia o el valor de estos estilos de codificación de bloque en Ruby?

¡Gracias de antemano!

1) cmds.each do |cmd| 
    end 

2) cmds.each { |cmd| 
    } 

código Ejemplo:

cmds = [ "create", "update", "list", "help" ] 

# Block style one 
# 
cmds.each do |cmd| 
    puts "loop1, cmd: #{cmd}" 
end 

# Block style two 
# 
cmds.each { |cmd| 
    puts "loop2, cmd: #{cmd}" 
} 
+0

no hay diferencia, el do/end one es simplemente más agradable. también corregí tu pregunta –

+0

Gracias Iraimbilanja, tus cambios tienen sentido para mí. –

+0

@Iraimbilanja: Hay una diferencia, como se describe en las respuestas. –

Respuesta

37

El equipo de rieles y muchas otras Rubyistas prefer a utilizar llaves para una línea de bloques y do...end para los multilínea.

La única diferencia funcional entre los dos es que la prioridad de un bloque do...end es menor que la de un bloque {...}.

+0

Son lo mismo sin embargo. Entonces, cuando use llaves, lo escribiría en una línea como: 'cmds.each {| cmd | pone "loop2, cmd: # {cmd}"} ' –

0

No creo que realmente importe, es solo una elección estética personal. Algunas personas prefieren usar la versión do...end cuando el bloque necesita múltiples líneas y la versión {...} cuando todo está en una línea.

13

Las dos formas son equivalentes.

El estilo recomendado es utilizar las llaves para bloques de una línea y usar "do" - "end" para bloques de varias líneas.

Editar:Austin Ziegler señaló (en el comentario a continuación) que las dos formas tienen niveles de precedencia de diferencia: Las llaves tienen mayor precedencia. Por lo tanto, al llamar a un método sin paréntesis, un bloque incluido en {} se vinculará con el último argumento en lugar del método que realiza la llamada.

En el siguiente ejemplo se sugirió por Austin:

def foo 
    yield 
end 

puts foo { "hello" } 

puts foo do 
    "hello" 
end 

Los primeros "puts" imprime "Hola": foo se llama a regresar "hola", que es el argumento que pone.

El segundo fianzas con un error:

in `foo': no block given 

Como en este caso el bloque de do-extremo se une con el método pone.

Gracias de nuevo a Austin por aclarar esto.

+6

No, no lo son. foo def rendimiento extremo pone foo { "Hola"} pone foo hacer; "Hola"; end Este último lanzará una excepción. El primero no (y se imprimirá "hola"). {} se une a #foo; do/end se une a #puts. –

+0

Gracias por señalar esto. He editado la respuesta que le da el crédito. Debería haber agregado realmente su propia respuesta para que el póster original pueda marcarla como la respuesta correcta. – nimrodm

2

En la mayoría de los casos, el estilo 1 se usa para bloques de varias líneas y el estilo 2 se usa para líneas simples.

La sintaxis do…end se asemeja mucho a otras estructuras de control Ruby (si, def, clase), por lo que usar eso para bloques mantiene el aspecto de su código consistente y claro. Pero no funciona bien para one-liners, razón por la cual la versión de corchetes es preferida allí.

10

La respuesta de Gordon es "The Ruby Way", y aunque es una práctica común poner una línea entre llaves, no es necesario.

También tenga en cuenta la facilidad con la que se puede actuar sobre el valor resultante:

cmds.each do |cmd| cmd.upcase! end.sort 

# Now, cmds = ["CREATE", "HELP", "LIST", "UPDATE"] 

Aunque es posible que vea ya cómo {} es más fácil de leer aquí, y por lo tanto prefiere que nadie más va a ver su código:

cmds.each { |cmd| cmd.upcase! }.sort 
+0

zandev, gracias por el consejo adicional sobre 'end.sort' –

21

Según the "Pickaxe" book (estoy mirando a la 2ª edición aquí), de Gordon correcta: la única diferencia es la precedencia:

p.356 (la cursiva es mía):

Braces have a high precedence; do has a low precedence. If the method invocation has parameters that are not enclosed in parentheses, the brace form of a block will bind to the last parameter, not to the overall invocation. The do form will bind to the invocation.

Ver también p.168 para un ejemplo.

1

Convencionalmente, el uso de {} está reservado para bloques de una línea, mientras que do...end es para bloques de varias líneas.

Debido a cómo {} no se utilizan en Rubí con tanta frecuencia como en otros lenguajes como C++ o Javascript, usando do...end cuando se les da la oportunidad en lugar de {} puede ayudar a que el código sea más legible para otros Rubyistas.

Tenga en cuenta que {} tiene prioridad sobre do...end.

Cuestiones relacionadas