redundant - ruby return method
¿Cuál es el punto de retorno en Ruby? (6)
La falta de pertinencia del return
en la última línea de la función es solo azúcar sintáctica de Ruby. En la mayoría de los lenguajes de procedimiento, debe escribir return
en cada función (no válida en C ++).
¿Cuál es la diferencia entre return
y solo poniendo una variable como la siguiente?
sin retorno
def write_code(number_of_errors)
if number_of_errors > 1
mood = "Ask me later"
else
mood = "No Problem"
end
mood
end
regreso
def write_code(number_of_errors)
if number_of_errors > 1
mood = "Ask me later"
else
mood = puts "No Problem"
end
return mood
end
No es necesario usar "return" si es la última línea que se ejecutará en el método, ya que Ruby devuelve automáticamente la última expresión evaluada.
Ni siquiera necesita ese "estado de ánimo" final, ni necesita esas asignaciones en la declaración IF.
def write_code(number_of_errors)
if number_of_errors > 1
"ERROR"
else
"No Problem"
end
end
puts write_code(10)
Salida:
ERROR
Ruby regresa siempre! la mejor manera es
def write_code(number_of_errors)
(number_of_errors > 1)? "ERROR" : "No Problem"
end
significa que si number_of_errors> 1 devolverá ERROR sino ningún problema
Su buen rubí le da esta buena característica de no especificar declaración de retorno explícitamente, pero siento que, como estándar de programación, uno siempre debe esforzarse por especificar declaraciones de "retorno" cuando sea necesario. Esto ayuda a hacer que el código sea más legible para alguien que proviene de diferentes antecedentes como C ++, Java, PHP, etc. y que aprende ruby. La declaración "return" no dañará nada, entonces, ¿por qué omitir la forma convencional y más estándar de regresar de las funciones?
Utilizo return cuando estoy revisando una lista, y quiero salir de la función si algún miembro de la lista cumple un criterio. Podría lograr esto con una sola declaración como:
list.select{|k| k.meets_criteria}.length == 0
en algunas situaciones, pero
list.each{|k| return false if k.meets_criteria}
es una línea también, con, en mi opinión, cierta flexibilidad añadida. Por ejemplo, el primer ejemplo asume que esta es la única línea en el método, y que queremos regresar desde este punto sin importar qué. Pero si esto es una prueba para ver si es seguro proceder con el resto del método, el primer ejemplo deberá manejarlo de una manera diferente.
EDITAR:
Para agregar cierta flexibilidad, considere la siguiente línea de código:
list_of_method_names_as_symbols.each{|k| list_of_objects.each{|j| return k if j.send(k)}}
Estoy seguro de que esto se puede lograr, en una línea, sin return
, pero fuera de mi cabeza, no veo cómo.
Pero ahora esta es una línea de código bastante flexible que se puede invocar con cualquier lista de métodos booleanos y una lista de objetos que implementan esos métodos.
EDITAR
Debe notarse que estoy asumiendo que esta línea está dentro de un método, no de un bloque.
Pero esto es principalmente una elección estilística, creo que en la mayoría de las situaciones, puede y posiblemente debería evitar el uso de return
.
return
te permite salir temprano:
def write_code(number_of_errors)
return "No problem" if number_of_errors == 0
badness = compute_badness(number_of_errors)
"WHAT?! Badness = #{badness}."
end
Si number_of_errors == 0
, entonces "No problem"
será devuelto inmediatamente. Al final de un método, sin embargo, es innecesario, como usted observó.
Editar: para demostrar que el return
sale inmediatamente, considere esta función:
def last_name(name)
return nil unless name
name.split(//s+/)[-1]
end
Si llama a esta función como last_name("Antal SZ")
, devolverá "SZ"
. Si lo llama como last_name(nil)
, devuelve nil
. Si el return
no abortó inmediatamente, intentaría ejecutar nil.split(//s+/)[-1]
, lo que arrojaría un error.