トラック
/
Elixir
Elixir
/
演習
/
パンとポーション
パンとポーション

パンとポーション

学習演習

はじめに

プロトコル

プロトコルは、データ型によって振る舞いを変えたいときに、Elixirでポリモーフィズムを実現するための仕組みです。

プロトコルはdefprotocolを使って定義し、1つ以上の関数ヘッダーを含みます。

defprotocol Reversible do
  def reverse(term)
end

プロトコルはdefimplを使って実装できます。

defimpl Reversible, for: List do
  def reverse(term) do
    Enum.reverse(term)
  end
end

プロトコルは、既存のElixirのデータ型や構造体に対して実装できます。

プロトコルの関数が呼び出されると、第1引数の型に基づいて、適切な実装が自動的に選ばれます。

説明

自分だけのロールプレイングゲームを開発しているとしましょう。ゲームの中には、_キャラクター_と_アイテム_が登場します。アイテムに対してできる操作はたくさんありますが、その1つが、キャラクターにアイテムを食べさせることです。

すべてのアイテムが食べられるわけではなく、食べられるアイテムがすべて同じ効果をキャラクターに及ぼすわけでもありません。食べると別のアイテムに変わるものもあります(たとえば、りんごを食べると、りんごの芯が残ります)。

こうした柔軟性を実現するために、一部のアイテムが実装できるEdibleプロトコルを作ることにしました。

1. 食べられるかどうかを定義する

RPG.Edibleプロトコルを作成します。このプロトコルが持つ関数は1つ、eatです。eat関数は、アイテムとキャラクターを受け取り、副産物とキャラクターを返します。

2. パンを食べられるようにする

RPG.LoafOfBreadアイテムにRPG.Edibleプロトコルを実装します。パンは、食べられるとキャラクターに体力ポイントを5与え、副産物はありません。

RPG.Edible.eat(%RPG.LoafOfBread{}, %RPG.Character{health: 31})
# => {nil, %RPG.Character{health: 36, mana: 0}}

3. マナポーションを食べられるようにする

RPG.ManaPotionアイテムにRPG.Edibleプロトコルを実装します。マナポーションは、食べられると、ポーションの強さと同じだけのマナポイントをキャラクターに与え、空のビンを生み出します。

RPG.Edible.eat(%RPG.ManaPotion{strength: 13}, %RPG.Character{mana: 50})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 100, mana: 63}}

4. 毒を食べられるようにする

RPG.PoisonアイテムにRPG.Edibleプロトコルを実装します。毒は、食べられると、キャラクターから体力ポイントをすべて奪い、空のビンを生み出します。

RPG.Edible.eat(%RPG.Poison{}, %RPG.Character{health: 3000})
# => {%RPG.EmptyBottle{}, %RPG.Character{health: 0, mana: 0}}
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Elixir Exercism

パンとポーションを始める準備はできましたか?

Exercismに登録すれば、58個のコンセプト168個の演習、そして本物の人間によるメンタリングとともに、Elixirを学んでマスターできます。すべて無料です。