2012-03-05 12 views
9

Debe ser fácil. Pensé, de la lectura de this blog post que podría devolver algo justo después de mi next comando:está devolviendo un valor de 'siguiente' una mala idea?

next "new value" if axis_range == "test"

Lo que realmente me gustaría hacer es registrar el motivo de la próxima en la misma línea:

next @logger.info('skipping this item because for fun') unless (elephants.size > 0)

No encuentro ninguna discusión sobre este uso de next en ruby doc. El código ciertamente funciona. Me doy cuenta de que puedo hacer esto con un bloque unless, pero esa línea de código es muy concisa.

dos preguntas:

  • ¿Existe un documento mejor en alguna parte?
  • ¿Es este uso de next un poco extraño y no 'ruby-ish'?

Respuesta

16

"Como los return y break palabras clave, next puede usarse solo, o que puede ser seguido por una expresión o una lista separada por comas de expresiones. Cuando next se utiliza en un bucle, ningún valor siguiente next se ignoran.En un bloque sin embargo, la expresión o expresiones se convierten en el "valor de retorno" de la declaración yield que invocó el bloque ". (El lenguaje de programación Ruby, David Flanagan & Yukihiro Matsumoto, 2008, página 150)

El libro da este ejemplo:

squareroots = data.collect do |x| 
    next 0 if x < 0 # return 0 for negative values 
    Math.sqrt(x) 
end 

y esta alternativa:

squareroots = data.collect do |x| 
    if (x < 0) then 0 else Math.sqrt(x) end 
end 
+0

Entre los dos diría que el segundo es más legible. – jcollum

+0

'squareroots = data.collect {| x | (x <0)? 0: Math.sqrt (x)} '(el operador ternario es mejor en este caso) – ndbroadbent

+1

En el primer ejemplo, la instrucción' next ... 'se comporta como una cláusula guard. Me gusta. ¡Gracias! – pdobb

0

Mi primera impresión es que es bastante evidente lo que hace la palabra clave next en el contexto de un ciclo, eso es algo bueno. El hecho de que "new value" es un resultado de next "new value" es un poco exagerado, pero puedo lograrlo.

Lo que me sorprende es que next @logger.info('skipping this item because for fun') probablemente sea difícil de entender. Realmente no es evidente que el resultado de la llamada info va a ser devuelto por next y creo que muchos de los desarrolladores serían rechazados.

Si bien el código puede ser más conciso, es difícil de entender. Yo haría un comentario sobre lo que está haciendo el código o iré con otra cosa.

Sin embargo, llama a tus dos preguntas. ¡Me encantaría ser un desarrollador manteniendo tu código con ese tipo de mentalidad!

+0

Gracias por el cumplido – jcollum

0

No tendría un problema inherente a menos que fuera justo en medio de muchos otros códigos complicados (trato de promediar 2 LOC por método, generalmente uno o dos que tienen de 4 a 8 líneas, y un montón que son solo una línea, promediando).

Si el código es largo y difícil de entender, he tenido mucho éxito tirando del método hacia su propio objeto. Simplemente hago que el método ejemplifique un objeto que hace su tarea y le pide el resultado, luego el código puede ser mucho más simple, a menudo reduciendo el ciclo a solo una línea o dos y permitiendo que tenga un método que hace este registro, que a continuación, podría manejarlo con una simple llamada a log_error o al nombre que crea apropiado.

En estos días considero que los procedimientos complejos son un olor que hay un objeto gestando en este método.

Cuestiones relacionadas