Viniendo de un fondo de Python, donde siempre hay una "forma correcta de hacerlo" (una forma "pitónica") cuando se trata de estilo, me pregunto si existe lo mismo para Ruby. He estado usando mis propias pautas de estilo, pero estoy pensando en publicar mi código fuente, y me gustaría que se adhiera a las reglas no escritas que puedan existir.
¿Es "The Ruby Way" escribir explícitamente los return
métodos? Lo he visto hecho con y sin, pero ¿hay una manera correcta de hacerlo? ¿Hay quizás un momento adecuado para hacerlo? Por ejemplo:
def some_func(arg1, arg2, etc)
# Do some stuff...
return value # <-- Is the 'return' needed here?
end
ruby
coding-style
return-value
Sasha Chedygov
fuente
fuente
Respuestas:
Antigua (y "contestada") pregunta, pero arrojaré mis dos centavos como respuesta.
TL; DR: no es necesario, pero puede hacer que su código sea mucho más claro en algunos casos.
Aunque no usar un retorno explícito puede ser "la forma de Ruby", es confuso para los programadores que trabajan con código desconocido o no están familiarizados con esta característica de Ruby.
Es un ejemplo un tanto artificial, pero imagine tener una pequeña función como esta, que agrega uno al número pasado y lo asigna a una variable de instancia.
¿Se suponía que era una función que devolvía un valor o no? Es realmente difícil decir qué quiso decir el desarrollador, ya que asigna la variable de instancia Y devuelve el valor asignado también.
Supongamos que mucho más tarde, aparece otro programador (tal vez no tan familiarizado con cómo Ruby regresa en función de la última línea de código ejecutada) y quiere poner algunas declaraciones de impresión para el registro, y la función se convierte en esto ...
Ahora la función está rota si algo espera un valor devuelto . Si nada espera un valor devuelto, está bien. Claramente, si en algún lugar más abajo de la cadena de código, algo que llama a esto espera un valor devuelto, fallará ya que no está recuperando lo que espera.
La verdadera pregunta ahora es esta: ¿esperaba algo realmente un valor devuelto? ¿Esto rompió algo o no? ¿Romperá algo en el futuro? ¡Quién sabe! Solo una revisión completa del código de todas las llamadas te lo hará saber.
Entonces, al menos para mí, el enfoque de mejores prácticas es ser muy explícito de que está devolviendo algo si es importante, o no devolver nada cuando no lo es.
Entonces, en el caso de nuestra pequeña función de demostración, suponiendo que deseamos que devuelva un valor, se escribiría así ...
Y sería muy claro para cualquier programador que devuelve un valor, y mucho más difícil para ellos romperlo sin darse cuenta.
Alternativamente, uno podría escribirlo así y omitir la declaración de devolución ...
Pero, ¿por qué molestarse en dejar de lado la palabra retorno? ¿Por qué no simplemente ponerlo allí y dejar 100% claro lo que está sucediendo? Literalmente no tendrá ningún impacto en la capacidad de rendimiento de su código.
fuente
return
agrega significado semántico al código, ¿por qué no? No es muy detallado: no estamos hablando de 5 líneas frente a 3, solo una palabra más. Prefiero verreturn
al menos en funciones (tal vez no en bloques) para expresar lo que el código realmente hace. A veces tiene que regresar a la mitad de la función: no omita la últimareturn
palabra clave en la última línea solo porque puede hacerlo . No favorezco la verbosidad en absoluto, pero sí la consistencia.side_effect()
y otro desarrollador decide (ab) usar el valor de retorno implícito de su procedimiento. Para solucionar esto, puede hacer sus procedimientos explícitamentereturn nil
.No. El buen estilo Ruby generalmente solo usaría un retorno explícito para un retorno temprano . Ruby es grande en el minimalismo de código / magia implícita.
Dicho esto, si un retorno explícito aclararía las cosas o facilitaría la lectura, no dañará nada.
fuente
return
ya tiene un significado semántico significativo como una SALIDA TEMPRANA a la función.return
en la última línea como una SALIDA TEMPRANA de todos modos?Personalmente uso la
return
palabra clave para distinguir entre lo que llamo métodos funcionales , es decir, métodos que se ejecutan principalmente por su valor de retorno, y métodos de procedimiento que se ejecutan principalmente por sus efectos secundarios. Entonces, los métodos en los que el valor de retorno es importante, obtenga unareturn
palabra clave adicional para llamar la atención sobre el valor de retorno.Utilizo la misma distinción cuando llamo a métodos: los métodos funcionales tienen paréntesis, los métodos de procedimiento no.
Y por último, pero no menos importante, también utilizo esa distinción con los bloques: los bloques funcionales obtienen llaves, los bloques de procedimiento (es decir, los bloques que "hacen" algo) obtienen
do
/end
.Sin embargo, trato de no ser religioso al respecto: con bloques, llaves y
do
/end
tienen precedencia diferente, y en lugar de agregar paréntesis explícitos para desambiguar una expresión, simplemente cambio al otro estilo. Lo mismo ocurre con la llamada al método: si agregar paréntesis alrededor de la lista de parámetros hace que el código sea más legible, lo hago, incluso si el método en cuestión es de naturaleza procesal.fuente
En realidad, lo importante es distinguir entre:
Ruby no tiene una forma nativa de distinguirlos, lo que lo deja vulnerable a escribir un procedimiento
side_effect()
y a otro desarrollador que decide abusar del valor de retorno implícito de su procedimiento (básicamente tratándolo como una función impura).Para resolver esto, saque una hoja del libro de Scala y Haskell y haga que sus procedimientos regresen explícitamente
nil
(akaUnit
o()
en otros idiomas).Si sigues esto, entonces usar una
return
sintaxis explícita o no solo se convierte en una cuestión de estilo personal.Para distinguir aún más entre funciones y procedimientos:
do/end
()
, mientras que cuando invoque funciones, noTenga en cuenta que Jörg W Mittag en realidad abogó al revés, evitando
()
los procedimientos, pero eso no es aconsejable porque desea que las invocaciones de métodos de efectos secundarios se distingan claramente de las variables, particularmente cuando el arity es 0. Consulte la guía de estilo Scala sobre invocación de métodos para detalles.fuente
function_a
, yfunction_a
fue escrito para llamar (y solo puedo operar llamando)procedure_b
, ¿esfunction_a
realmente una función? Devuelve un valor, cumpliendo su requisito de funciones, pero tiene un efecto secundario, cumpliendo los requisitos de los procedimientos.function_a
podría contener un árbol deprocedure_...
llamadas, comoprocedure_a
podría contener un árbol defunction_...
llamadas. Al igual que Scala pero a diferencia de Haskell, Ruby no puede garantizar que una función no tenga efectos secundarios.La guía de estilo dice que no deberías usar
return
en tu última declaración. Todavía puede usarlo si no es el último . Esta es una de las convenciones que la comunidad sigue estrictamente, y usted también debería hacerlo si planea colaborar con alguien que use Ruby.Dicho esto, el argumento principal para usar
return
s explícito es que es confuso para las personas que vienen de otros idiomas.Una heurística común para la longitud del método (excluyendo getters / setters) en java es una pantalla . En ese caso, es posible que no esté viendo la definición del método y / o que ya se haya olvidado de dónde regresaba.
Por otro lado, en Ruby es mejor seguir métodos de menos de 10 líneas . Dado eso, uno se preguntaría por qué tiene que escribir ~ 10% más de declaraciones, cuando están claramente implícitas.
Como Ruby no tiene vacío métodos y todo es mucho más conciso, solo está agregando gastos generales para ninguno de los beneficios si utiliza
return
s explícito .fuente
Estoy de acuerdo con Ben Hughes y no estoy de acuerdo con Tim Holt, porque la pregunta menciona la forma definitiva en que Python lo hace y pregunta si Ruby tiene un estándar similar.
Lo hace.
Esta es una característica tan conocida del lenguaje que cualquier persona que esperara depurar un problema en ruby debería saberlo razonablemente.
fuente
return
palabra clave cuando no es necesario.Es cuestión de qué estilo prefieres en su mayor parte. Debe usar la palabra clave return si desea regresar desde algún lugar en medio de un método.
fuente
Como dijo Ben. El hecho de que "el valor de retorno de un método ruby es el valor de retorno de la última instrucción en el cuerpo de la función" hace que la palabra clave return rara vez se use en la mayoría de los métodos ruby.
fuente
if failed_check then nil else @list end
? Eso es realmente funcional .