Los protocolos son un mecanismo para lograr polimorfismo en Elixir cuando quieres que el comportamiento varíe según el tipo de datos.
Los protocolos se definen con defprotocol y contienen una o más cabeceras de funciones.
defprotocol Reversible do
def reverse(term)
end
Los protocolos pueden implementarse con defimpl.
defimpl Reversible, for: List do
def reverse(term) do
Enum.reverse(term)
end
end
Un protocolo puede implementarse para cualquier tipo de datos de Elixir que ya exista o para un struct.
Cuando se invoca una función de un protocolo, la implementación adecuada se elige automáticamente en función del tipo del primer argumento.
Estás desarrollando tu propio videojuego de rol. En tu juego hay personajes y objetos. Una de las muchas acciones que puedes hacer con un objeto es hacer que un personaje se lo coma.
No todos los objetos son comestibles, y no todos los objetos comestibles tienen los mismos efectos en el personaje. Algunos objetos, cuando se comen, se convierten en otro objeto (por ejemplo, si te comes una manzana, te queda el corazón de la manzana).
Para permitir toda esa flexibilidad, decidiste crear un protocolo Edible que algunos de los objetos pueden implementar.
Crea el protocolo RPG.Edible. El protocolo tiene una función: eat. La función eat acepta un objeto y un personaje, y devuelve un subproducto y un personaje.
Implementa el protocolo RPG.Edible para el objeto RPG.LoafOfBread. Cuando se come, una hogaza de pan le da al personaje 5 puntos de salud y no tiene subproducto.
RPG.Edible.eat(%RPG.LoafOfBread{}, %RPG.Character{health: 31})
# => {nil, %RPG.Character{health: 36, mana: 0}}
Implementa el protocolo RPG.Edible para el objeto RPG.ManaPotion. Cuando se come, una poción de maná le da al personaje tantos puntos de maná como la fuerza de la poción, y produce una botella vacía.
RPG.Edible.eat(%RPG.ManaPotion{strength: 13}, %RPG.Character{mana: 50})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 100, mana: 63}}
Implementa el protocolo RPG.Edible para el objeto RPG.Poison. Cuando se come, un veneno le quita al personaje todos los puntos de salud y produce una botella vacía.
RPG.Edible.eat(%RPG.Poison{}, %RPG.Character{health: 3000})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 0, mana: 0}}
Regístrate en Exercism para aprender y dominar Elixir con 58 conceptos168 ejercicios y mentoría humana real, todo gratis.