2010-07-24 13 views
5

Estoy seguro de que hay una manera de rubí más idiomática para escribir el código de abajo:Más forma idiomática de rubíes de escribir @var = obj ['blah'] a menos que obj ['blah'] nil?

@var = obj['blah'] unless obj['blah'].nil? 

Tengo una carga completa de estos para hacer (véase más adelante), y tiene que haber una manera mejor!

@num_x = obj['num_x'] unless obj['num_x'].nil? 
@num_y = obj['num_y'] unless obj['num_y'].nil? 
@num_iterations = obj['num_iterations'] unless obj['num_iterations'].nil? 
@pe = obj['pe'] unless obj['pe'].nil? 

Tengo la sensación de que el operador ||= puede ser útil, pero parece que no puede funcionar bastante encontrar la manera de usarlo.

+3

'|| =' es para comprobar si la variable en sí es nula. ¿Qué está tratando de lograr? ¿Por qué es un problema si estos ivars son nulos? – jtbandes

Respuesta

2

el más corto que se me ocurre para esta necesidad común es

@var = obj['blah'] or @var 

aunque si obj['blah'] puede haber false, tendrá que ir con su versión original.

El operador ||= prueba el lado izquierdo, no el derecho, por lo que no se aplica aquí.

+0

Su código es ligeramente diferente: en su ejemplo '@ var' no se actualiza es' obj ['blah'] = false'. En el ejemplo de OP, siempre se actualiza, excepto que el valor es 'nil'. – Veger

+0

@Veger: por supuesto. es por eso que menciono que si 'obj ['blah']' puede ser falso, necesitas la versión original. – Peter

+0

¡Ah, lo siento, no lo noté! Oh, cambiaste la respuesta ... :) Ahora siempre estás actualizando '@ var' No sé si es muy eficiente, pero está en corto en código ... – Veger

3

Dependiendo de las circunstancias, ya menos que las variables de instancia que ya tienen un valor existente que desea conservar si el valor de obj es nil entonces podría no ser un problema de dejar que ellos pueden configurar para nil.

Alternativamente, se podría escribir un poco de función auxiliar como:

def set_instance_variables_for_non_nil_values(h, *keys) 
    keys.each do |key| 
    instance_variable_set "@#{key}", h[key] unless h[key].nil? 
    end 
end 

Luego, en el código de ejemplo, usted podría utilizar de esta manera:

set_instance_variables_for_non_nil_values obj, 'num_x', 'num_y', 
    'num_iterations', 'pe' 
+0

Esta es una buena solución que hace lo que hizo la pregunta. Sin embargo, diría que la configuración masiva de variables de instancia como esta es una mala idea a menos que tengas una buena razón. –

1

De esta manera:

obj['blah'] && var = obj['blah'] 
0

si @var ya tiene un valor que no es nulo o falso, entonces puede usar

@var &&= obj['blah'] 

pero estaría tentado de encontrar una solución más simple tal vez la fusión de hashes si hay muchos valores.

tales como:

obj = {:num_x => 23, :num_y => 75, :pe => 99} 

locals = {:num_x => 1, :num_y => 2, :num_iterations => 3, :pe => 4} 

puts locals.inspect #=> {:num_y=>2, :pe=>4, :num_iterations=>3, :num_x=>1} 

locals.merge! obj 

puts locals.inspect #=> {:num_y=>75, :pe=>99, :num_iterations=>3, :num_x=>23} 

que se utiliza para las opciones en muchas joyas que he visto el establecimiento.

Cuestiones relacionadas