¿Cómo escribo una condición if compleja de varias líneas en Ruby?


¿Cómo escribo esta instrucción multi-line, complex condition if en Ruby?

  if ( (aa != nil && self.prop1 == aa.decrypt)   
      || (bb != nil && self.prop2 == bb.decrypt)  
    ) && (self.id.nil? || self.id != id) 
    return true
  end

Estoy recibiendo Syntax error; unexpected tOROP.

En Java, podría escribir

if (
     ( (aa != null && aa.prop1.equals(aa.decrypt()))
     || (bb != null && bb.prop2.equals(bb.decrypt()))
     )
     && (this.id != id)
   ) {

   return true;
}
Author: Chloe, 2014-01-29

2 answers

La respuesta corta es que el operador necesita estar al final de la línea para decirle a Ruby que continúe leyendo la siguiente línea como parte de la instrucción, por lo que esto funcionaría:

if ( (aa != nil && self.prop1 == aa.decrypt) ||
   (bb != nil && self.prop2 == bb.decrypt) ) &&
   (self.id.nil? || self.id != id)
  return true
end

Dicho esto, probablemente puede reducir la lógica lanzando excepciones basadas en los valores de entrada y eliminando algunas comprobaciones redundantes (estoy haciendo algunos saltos aquí sobre cómo se verán sus variables, pero entiende la idea.)

raise 'aa must support decrypt' unless aa.respond_to? :decrypt
raise 'bb must support decrypt' unless bb.respond_to? :decrypt
if prop1 == aa.decrypt || prop2 == bb.decrypt
  if self.id != id
    return true
  end
end
 68
Author: Kyle Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-28 21:52:19

Necesita escapar los espacios en blanco con el carácter de barra invertida, es feo pero lo necesita si desea dividir las condiciones en varias líneas. Eso o dejar el operador booleano en la línea anterior. Así que cualquiera de estos funcionará:

if ( (aa != nil && self.prop1 == aa.decrypt)\
      || (bb != nil && self.prop2 == bb.decrypt)\
    ) && (self.id.nil? || self.id != id) 
    return true
  end

O:

if ( (aa != nil && self.prop1 == aa.decrypt) || 
      (bb != nil && self.prop2 == bb.decrypt)) &&
    (self.id.nil? || self.id != id) 
    return true
  end

Personalmente suelo decidir poner todas o cada una de las condiciones en un método que documente lo que se está decidiendo:

def everythings_cool?
  ( (aa != nil && self.prop1 == aa.decrypt) || 
          (bb != nil && self.prop2 == bb.decrypt)) &&
        (self.id.nil? || self.id != id) 
end

Entonces:

if everythings_cool?
  # do stuff
 17
Author: DiegoSalazar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-28 22:03:14