En Elixir, el condicional case nos permite combinar el poder del pattern matching con la toma de decisiones condicionales, lo que resulta en una herramienta muy versátil para manejar múltiples casos de forma clara y elegante. A diferencia de if o cond, que evalúan condiciones booleanas, case evalúa una expresión y la compara contra varios patrones, ejecutando el bloque correspondiente al primer patrón que coincida.
Para usar case, primero definimos la expresión que queremos evaluar. Por ejemplo, si tenemos una variable exp que contiene el resultado de una operación, podemos escribir:
case exp do
patrón_1 -> expresión_1
patrón_2 -> expresión_2
...
end
Cada patrón a la izquierda de la flecha -> se intenta hacer coincidir con el valor de exp. Si el patrón encaja, se ejecuta la expresión a la derecha. Por ejemplo, si exp es {:ok, "hola"}, podemos hacer:
case exp do
{:ok, x} -> "Ha resuelto correctamente con #{x}"
{:error, _} -> "No ha resuelto correctamente"
end
Aquí, el patrón {:ok, x} hace un pattern match con la tupla, y además vincula la variable x al valor "hola". Esa variable solo existe dentro del bloque de la flecha, por lo que no podemos usar x fuera de ese contexto. Si no necesitamos usar una variable, podemos reemplazarla por _ para evitar warnings de variables no usadas.
Una característica muy potente de case es que podemos añadir guardas a los patrones para afinar aún más las condiciones. Por ejemplo, podemos hacer que un patrón solo coincida si una variable es un número:
case exp do
{:ok, x} when is_number(x) -> "Ha resuelto correctamente con un número: #{x}"
{:ok, _} -> "Ha resuelto correctamente con algo que no es número"
{:error, _} -> "No ha resuelto correctamente"
end
Las guardas se añaden con la palabra clave when y permiten combinar el pattern matching con condiciones adicionales.
Es importante tener un patrón comodín al final del bloque case, que suele ser _, para cubrir cualquier caso no previsto. Esto evita errores en tiempo de ejecución si la expresión no coincide con ninguno de los patrones anteriores. Por ejemplo:
case exp do
{:ok, x} -> "Ok con #{x}"
{:error, _} -> "Error"
_ -> "Caso no previsto"
end
Si colocamos el patrón comodín al principio, este atrapará cualquier valor y los patrones siguientes nunca se evaluarán, por lo que siempre debe ir al final.
En cuanto a cuándo usar case frente a cond o if, la regla general es que case es ideal cuando queremos hacer pattern matching sobre una expresión, mientras que cond es más adecuado para evaluar múltiples condiciones booleanas. El if se reserva para condiciones simples. Así, case nos permite escribir código más expresivo y claro cuando trabajamos con estructuras de datos que queremos descomponer o analizar según su forma.
En definitiva, case es una herramienta fundamental en Elixir que combina la potencia del pattern matching con la flexibilidad de los condicionales, permitiéndonos manejar múltiples escenarios de forma elegante y segura.