ElixirのiexでとりこぼしたPIDをひろう

（この記事は[「fukuoka.ex x ザキ研 Advent Calendar 2017」](https://adventar.org/calendars/2873)の5日目です)

昨日は @zacky1972 さんの[「 ZEAM開発ログ v.0.2.0 Node.js と同じ原理の軽量コールバックスレッドを Elixir に実装してみた (背景編)」](https://qiita.com/zacky1972/items/404301b783d2e66ed0a5) でした。

# おしらせ

本日開催される「Fukuoka.ex#11」にて、Mnesia-Flow-WebSocketを使った発表をする予定です。若干の空きがございますので、Elixirにご興味がある方はご参加下さい！

[![image.png](https://connpass-tokyo.s3.amazonaws.com/thumbs/cb/13/cb130a03343bc310b07244c308b940db.png)](https://fukuokaex.connpass.com/event/87241)



#はじめに

Elixirはプロセスやサーバーが簡単に作れる素晴らしくも珍しい処理系です。
iexという対話環境の中からでも気軽にプロセスとサーバーを扱うことができます。

身近に初心者の方が増えてきたので、iexリテラシー向上のために
書きたいと思います。（本当は昨日知りました:smirk:）

気軽に「プロセスで並行処理ができますよ！」と賑やかな人達にそそのかされた方も、口車に乗って試してみましょう:grinning:

# GenServerでサーバーを立てる

先に動作風景から行きます。コピペでサーバーが起動するところです。
![GenServer.gif](https://qiita-image-store.s3.amazonaws.com/0/66748/bd01d62a-3f9a-a4cd-08bf-afbbd9f11668.gif)

５秒ごとにカウントを行うサーバーを立てるコードは、
GenServerを使うとこんな感じです。（上記GIFアニメは1秒間隔）

```elixir
defmodule MyServer do
  use GenServer

  def start_link(counter) do
    GenServer.start_link(__MODULE__, counter)
  end

  def init(counter) do
    schedule_job()
    {:ok, counter}
  end

  def handle_info(:next_tick, counter) do
    IO.inspect my_server: counter
    schedule_job()
    {:noreply, counter+1}
  end

  defp schedule_job() do
    Process.send_after(self(), :next_tick, 5000)
  end
end
```

上記をiexにコピペすると、次のように受理されると思います。

```
{:module, MyServer,
 <<70, 79, 82, 49, 0, 0, 15, 84, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 1, 202,
   0, 0, 0, 46, 15, 69, 108, 105, 120, 105, 114, 46, 77, 121, 83, 101, 114, 118,
   101, 114, 8, 95, 95, 105, 110, 102, 111, ...>>, {:schedule_job, 0}}
iex(5) >
```

サーバーの定義が、サクっと終わったので早速起動します。

```
iex(2)> MyServer.start_link(0)
```

五秒に１回次のような表示が出ます。

```elixir
{:ok, #PID<0.692.0>}
[my_server: 0]
[my_server: 1]
[my_server: 2]
```

別プロセスで動いてるのを目の当たりにできました。本当に簡単にサーバーが立てれるんですね。

# サーバーを止めたい

さて、サーバーがコピペで作れることを堪能した後は、サーバーを止めたいですね。

[GenServerにはstopという関数](https://hexdocs.pm/elixir/GenServer.html#stop/3)があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66748/d2ad74ae-6082-215e-5aab-276b8fbed042.png)


引数は「server」です。

**「serverってどこで手に入るの？」**


実は、サーバーをスタートさせた直後に出る`#PID`なのでした

```
{:ok, #PID<0.692.0>}
      ↑　こいつです   
```

つまり、

```
{:ok, pid} = MyServer.start_link(0)
```
としてタプルにパターンマッチする変数で受け取っていれば
次のコードで止められたわけです。

```elixir
iex(6)> GenServer.stop(pid)
```

・・・・・なんということでしょう。

大事なはずの**「PIDを野にこぼしてきてしまった」**わけです。

無念の `Ctrl-\` でiexを抜けるしかありません！

・・・と次で示す技を知らなかったら、こうなります。
軽いストレスですね ><

# PIDを拾う

でも、今日からは違います。

```elixir
iex(6)> GenStage.stop( pid(0,692,0) )
:ok
```
無事にサーバーを止めることができました！

こぼれた文字列を拾えば、pidになるのです。
これでまた、楽しくサービスのプログラミングができますね。

ちなみに、次の書き方でもOKです。

```elixir
iex(5)> GenStage.stop( pid("0.692.0") )
:ok
```

本能的にpidをコピペして行けそうな、この書き方は残念ながらNGです。

```elixir
iex(6)> GenStage.stop( pid("#PID<0.692.0>") )  # NG
```

#おわりに

iexのリテラシーを上げることで、素晴らしい体験が待っています。
Elixirでサービスのプログラミンを楽しみましょう！

明日は @kobatakoさんの「GraphQL for Elixir#1 基本的な実装について考える」です。お楽しみに。

# p.s.「いいね」よろしくお願いします

よろしければ，ページ左上の ![image.png](https://qiita-image-store.s3.amazonaws.com/0/155423/4d515047-cc48-382e-c2b1-3ad0cc50dbbf.png) や ![image.png](https://qiita-image-store.s3.amazonaws.com/0/155423/a4e3da58-70a3-4197-95a2-6a6906650d01.png) のクリックをお願いしますー:bow:
ここの数字が増えると，書き手としては「ウケている」という感覚が得られ，記事を更に進化させていくモチベーションになりますので，もっとElixirネタを見たいというあなた，私たちと一緒に盛り上げてください！:tada: