Crystal tiene un tipo llamado Nil, que solo puede tener un valor: nil.
Se usa para representar la ausencia de un valor y es similar a null o None en otros lenguajes.
Los valores nil se pueden devolver desde varios métodos; por ejemplo, String#[]?, que devuelve nil si el índice está fuera de rango.
"foo"[10]? # => nil
Crystal tiene lo que se conoce como verificación de referencias nulas, lo que significa que, por defecto, ningún tipo puede ser nil.
Esto quiere decir que no puedes asignar nil a una variable a menos que la declares explícitamente como de tipo Nil.
A su vez, esto significa que el compilador verificará automáticamente las referencias nulas.
Existen varios enfoques para manejar los valores nil.
nil es un valor falsey, al igual que false.
Esto significa que, en sentencias y en otros lugares donde se espera un valor falsey o truthy, se tratará igual que false.
if nil
puts "nil is truthy"
else
puts "nil is falsey"
end
# => nil is falsey
Esto significa que no se tomará la rama truthy si una variable que puede ser nil tiene el valor nil.
foo = "boo"[2]? # It is possible that foo is nil
if foo
p foo.class # => Char
end
Crystal tiene un método que se puede usar para comprobar si un valor es nil.
Se llama nil? y está disponible en todos los objetos.
foo = "boo"[2]?
if foo.nil?
puts "foo is nil"
else
puts "foo is not nil"
end
Esto es un poco distinto cuando solo usas el valor en un condicional, ya que en los ejemplos anteriores tanto false como nil se trataban como falsos.
Aquí solo nil se trata como falsey, porque si el valor fuera false no sería nil y, por lo tanto, sería truthy.
La forma más fácil de lidiar con los valores nil es asegurarte de que nunca lleguen a ser nil en primer lugar.
El operador or (||) se usa a menudo cuando se trabaja con Bools, pero, si se entiende bien, también se puede usar para trabajar con valores nil.
El operador or comprueba si el primer valor es truthy; si no lo es, se usa el segundo valor.
Esto se puede aprovechar para que, si el valor es nil, sea falsey y, por lo tanto, se use el segundo valor.
"foo"[10]? || "bar" # => "bar"
Su Majestad ofrece una cena en Copenhague, la capital de la Unión de Kalmar. Es la fiesta más grande del año y todos los nobles están invitados. Pero por todo el país corren rumores de que hay un complot para envenenar a Su Majestad.
Su Majestad te ha pedido a ti, el buscador real de venenos, que averigües si alguna comida o bebida está envenenada. Su Majestad planea servir solo Mushroom pasties como comida, pero en cuanto a las bebidas, hay una gran variedad.
Hay una gran probabilidad de que la comida esté envenenada si no es la que ordenó Su Majestad. Si la comida no es la que ordenó Su Majestad, hay que desecharla.
Implementa el método check_food?, que recibe el argumento food, el cual contiene el nombre de la comida como un String.
El método debe devolver la comida si es Mushroom pasties; de lo contrario, debe devolver nil.
CastleDinner.check_food?("Mushroom pasties")
# => "Mushroom pasties"
CastleDinner.check_food?("Bread")
# => nil
Es posible que la bebida esté envenenada, pero es un poco más difícil saber si lo está.
La bebida está envenenada si no incluye la letra i en su nombre; no importan las mayúsculas y minúsculas.
Hay que desechar la bebida si está envenenada.
Implementa el método check_drink?, que recibe el argumento drink, el cual contiene el nombre de la bebida como un String.
El método debe devolver la bebida si no está envenenada; de lo contrario, debe devolver nil.
CastleDinner.check_drink?("Apple juice")
# => "Apple juice"
CastleDinner.check_drink?("Tea")
# => nil
Su Majestad no querría preocupar a sus invitados por el veneno en la comida. Por lo tanto, si la bebida está envenenada, hay que reemplazarla por una nueva, en concreto Apple juice.
Implementa el método replace_drink, que recibe el argumento drink, el cual contiene el nombre de la bebida como un String.
El método debe devolver la bebida si no está envenenada; de lo contrario, debe devolver "Apple juice".
CastleDinner.replace_drink("Orange juice")
# => "Orange juice"
CastleDinner.replace_drink("Tea")
# => "Apple juice"
Regístrate en Exercism para aprender y dominar Crystal con 26 conceptos142 ejercicios y mentoría humana real, todo gratis.