¿Cómo puedo escribir mejor código para pasar argumentos de clave-valor?

Quiero escribir código para Ruby con un estilo más parecido a Ruby y me encontré con un problema al trabajar con el paso de argumentos.

tengo que ver si ABC es nulo o no. Si ABC es nulo, pasaría otro símbolo a dosomething, si no, pasaría otro tipo de valor hash para calcular.

Dado que Ruby no es como Java, puede pasar un tipo diferente de argumento (claves diferentes).

¿Cómo puedo hacer que el siguiente código sea más hermoso?

La fusión de do_manything, do_otherthings, do_manythings_again en una sola función no es la respuesta I porque yo llamaría dosomething en muchos lugares en mi código:

if ABC.nil?
Apple.dosomething (:foo => DEF) { |a| 
     a.do_manything
     a.do_otherthings
     a.do_manythings_again  
}
else
Apple.dosomething (:bar => ABC) { |a| 
     a.do_manything
     a.do_otherthings
     a.do_manythings_again  
}
end

preguntado el 03 de mayo de 12 a las 17:05

a menos que ABC puede ser nil y false (por lo que necesita distinguir uno del otro), no es idiomático escribir un explícito .nil? cheque. -

3 Respuestas

Usando el operador ternario.

Apple.dosomething (ABC.nil? ? {foo:DEF} : {bar:ABC}) do |a|
  a.do_manything
  a.do_otherthings
  a.do_manythings_again
end

Aquí está el formato condition ? return_if_true : return_if_false

contestado el 03 de mayo de 12 a las 17:05

En una revisión de código, diría que poner una declaración ternaria en la llamada al método no es una buena práctica. - el hombre de hojalata

Si. Más difícil de leer/más complicado, aunque podemos escribir de esa manera, piense en el mantenimiento a largo plazo o en lo que alguien más pensaría cuando lo encuentre. Cada vez que tenemos que detenernos para analizar el código en nuestra cabeza, aumentamos la posibilidad de un error. Este uso particular es bastante seguro porque es un ejemplo simple. Imagine un método con un montón de parámetros, o una gran inicialización de hash usando asignaciones ternarias, frente a uno sin ellos, y encuentre un término medio de legibilidad y concisión. - el hombre de hojalata

Puedes cambiar el hash que envías:

opts = ABC.nil? ? {foo:DEF} : {bar:ABC}
Apple.dosomething(opts) do |a|
  do_many_things
  do_other_things
  do_many_things_again
end

... o puedes pasar una lambda como bloque:

stuff_to_do = ->(a) do
  do_many_things
  do_other_things
  do_many_things_again
end

if ABC.nil?
  Apple.dosomething(foo:DEF,&stuff_to_do)
else
  Apple.dosomething(bar:ABC,&stuff_to_do)
end

contestado el 03 de mayo de 12 a las 18:05

Podrías hacer esto:

options = if ABC.nil? then { foo: DEF } else { bar: ABC } end

Apple.do_something options do |apple| 
  apple.instance_eval do
    do_many_things
    do_other_things
    do_many_things_again
  end
end

Por convención, las palabras en nombres e identificadores están separadas por guiones bajos (_) y do/end se utiliza para bloques de varias líneas.

Además, creo que esta pregunta pertenece a Revisión de código.

Respondido 13 Abr '17, 13:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.