entre - ruby on rails lenguaje de programacion
C#?? operador en Ruby? (4)
¿Es posible implementar el ?? operador en Ruby?
a = nil
b = 1
x = a ?? b # x should == 1
x = b ?? 2 # x should == 1
En Ruby, los operadores booleanos en cortocircuito ( ||
, &&
, &&
) no devuelven true
o false
, sino el primer operando que determina el resultado de la expresión completa. Esto funciona, porque Ruby tiene una idea bastante simple de la verdad. O más bien, tiene una idea bastante simple de falsedad: nil
es falso, y obviamente false
es falso. Todo lo demás es verdad
Entonces, ya que ||
es verdadero cuando al menos uno de sus operandos es verdadero, y los operandos se evalúan de izquierda a derecha, esto significa que a || b
a || b
devuelve a
, cuando a
es verdadero. Pero cuando a
es falso, entonces el resultado de la expresión depende únicamente de b
, y así se devuelve b
.
Eso significa que, como nil
es falso, puedes usar ||
en lugar de ??
para los ejemplos que diste (También está el ingenioso operador a ||= b
, que funciona como a || a = b
, pero no del todo).
Sin embargo, eso solo funciona, porque no usas booleanos en tus ejemplos. Si espera tratar con valores booleanos, eso no funcionará:
b = false
x = b || 2 # x should be == false, but will be 2
En ese caso, tendrá que usar #nil?
y una expresión condicional:
b = false
x = unless b.nil? then b else 2 end # x should be == 2
o usando el operador condicional ternario:
b = false
x = b.nil? ? 2 : b # x should be == false
Si lo desea, puede envolverlo en un buen método:
class Object
def _? b = nil
return self
end
end
class NilClass
def _? b = nil
return yield if block_given?
return b
end
end
b = false
x = b._? { 2 } # x should be == false
x = b._? 2 # x should be == false
Este bonito fragmento te lo trajo el polimorfismo, las clases abiertas y el hecho de que nil
es en realidad un objeto que representa la nada (a diferencia de, por ejemplo, Java, donde null
realidad no es nada).
Está buscando una asignación condicional:
a ||= b # Assign if a isn''t already set
y el || operador
a = b || 2 # Assign if b is assigned, or assign 2
Existe la gema coalesce , que es lo más cercano que obtendrás.
nil || 5 # => 5
false || 5 # => 5 :(
false._? 5 # => false :)
x = b || 2
It ( ??
en C #) se llama el operador de coalescencia.