Skip to content

Latest commit

 

History

History
84 lines (71 loc) · 1.79 KB

19.2.md

File metadata and controls

84 lines (71 loc) · 1.79 KB

19.2 エージェント

エージェント:

  • 状態を持つバックグラウンドプロセス
  • 初期状態はエージェント開始時に渡した関数で決まる

Agent.get(agent, fun, timeout \\ 5000)

  • agent: エージェントのディスクリプタ
  • fun: 現在の状態を変換する関数
  • timeout: タイムアウトまでの時間

指定した無名関数を使って状態を取得する

Agent.update(agent, fun, timeout \\ 5000)

  • agent: エージェントのディスクリプタ
  • fun: 現在の状態を変換する関数
  • timeout: タイムアウトまでの時間

指定した無名関数を使って状態を更新する

> {:ok, count} = Agent.start(fn -> 0 end)
{:ok, #PID<0.103.0>}
> Agent.get(count, &(&1))
0
> Agent.update(count, &(&1 + 1))
:ok
> Agent.update(count, &(&1 + 1))
:ok
> Agent.get(count, &(&1))
2

Agent.start(fun, options \\ [])

  • fun: 初期状態を設定する関数
  • options:
    name: エージェントの名前を指定する 詳しくは Agent.start_link/2 のAPI参照

現在のプロセスとリンクせずにエージェントを起動する

エージェントに名前を指定する例

gent.start(fn -> 1 end, name: Sum)
{:ok, #PID<0.110.0>}
> Agent.get(Sum, &(&1))
1
> Agent.update(Sum, &(&1 + 99))
:ok
> Agent.get(Sum, &(&1))
100

典型的な例 gen_server の実装と似ている => エージェントを使うと抽象化できる

> c "tasks/agent_dict.exs"
[Frequency]
> Frequency.start_link
{:ok, #PID<0.108.0>}
> Frequency.add_word "dave"
:ok
> Frequency.words
["dave"]
> Frequency.add_word "was"
:ok
> Frequency.add_word "here"
:ok
> Frequency.add_word "he"
:ok
> Frequency.add_word "was"
:ok
> Frequency.words
["dave", "he", "here", "was"]
> Frequency.count_for("dave")
1
> Frequency.count_for("was")
2