4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixirのパイプ演算子は川の流れの如く

Last updated at Posted at 2025-11-04

アントニオ猪木さんが朗読した有名な詩に、「道」があります。

この道を行けばどうなるものか
危ぶむなかれ
危ぶめば道はなし
踏み出せば
その一足が道となり
その人足が道となる
迷わず行けよ
行けば分かるさ

シンプルですが、深い意味があります。データが流れる道、処理が進む道。パイプ演算子はまさに「道」を作ります。

プログラミングも同じです。データの流れに逆らわず、自然に処理を繋げていく。それがElixirのパイプ演算子 |> の哲学です。


ネストの地獄──流れに逆らうコード

命令型言語の苦しみ

# ❌ ネストの地獄(読みにくい)
result = String.upcase(String.trim(String.replace(input, "a", "b")))

このコードは内側から外側へ読まなければなりません。

  1. String.replace(input, "a", "b") を実行
  2. その結果を String.trim() に渡す
  3. さらにその結果を String.upcase() に渡す

人間の思考の流れに逆らっています。

もっと複雑な例

# ❌ さらに深いネスト
result = 
  Enum.map(
    Enum.filter(
      Enum.map(
        String.split(input, "\n"),
        &String.trim/1
      ),
      fn line -> line != "" end
    ),
    &String.upcase/1
  )

これは川の流れではなく、渦巻きです。
まるで卍固めです。振りほどくのは困難です。


パイプライン演算子──川の流れの如く

Elixirの美しさ

# ✅ パイプライン演算子(読みやすい)
result = input
  |> String.replace("a", "b")
  |> String.trim()
  |> String.upcase()

データが上から下へ左から右へ流れます。

これが川の流れです。

複雑な処理も美しく

# ✅ パイプラインで表現
result = input
  |> String.split("\n")
  |> Enum.map(&String.trim/1)
  |> Enum.filter(fn line -> line != "" end)
  |> Enum.map(&String.upcase/1)

処理の流れが一目でわかります。


実例:ログ解析パイプライン

要件

アクセスログから、エラー(ステータスコード500以上)を抽出し、IPアドレスのリストを作成する。

命令型の苦しみ

# ❌ ネストの地獄
defmodule LogAnalyzer do
  def extract_error_ips(log_text) do
    Enum.map(
      Enum.filter(
        Enum.map(
          String.split(log_text, "\n"),
          fn line ->
            case Regex.run(~r/^(\S+).*HTTP\/\d\.\d" (\d+)/, line) do
              [_, ip, status] -> {ip, String.to_integer(status)}
              _ -> nil
            end
          end
        ),
        fn
          {_ip, status} when status >= 500 -> true
          _ -> false
        end
      ),
      fn {ip, _status} -> ip end
    )
    |> Enum.uniq()
  end
end

読むだけで疲れます。

パイプラインの美しさ

まず、ログデータを用意します。

# ログデータ(ヒアドキュメント)
log_data = """
192.168.1.1 - - [04/Nov/2025:10:15:30 +0900] "GET /index.html HTTP/1.1" 200 1234
192.168.1.2 - - [04/Nov/2025:10:16:45 +0900] "POST /api/users HTTP/1.1" 500 567
192.168.1.3 - - [04/Nov/2025:10:17:12 +0900] "GET /about.html HTTP/1.1" 200 890
192.168.1.2 - - [04/Nov/2025:10:18:33 +0900] "GET /api/posts HTTP/1.1" 503 234
192.168.1.4 - - [04/Nov/2025:10:19:01 +0900] "GET /contact.html HTTP/1.1" 200 456
"""

エラー(500番台)のIPアドレスを抽出してみましょう。

# ✅ 川の流れの如く
defmodule LogAnalyzer do
  def extract_error_ips(log_text) do
    log_text
    |> String.split("\n")
    |> Enum.map(&parse_log_line/1)
    |> Enum.filter(&is_error?/1)
    |> Enum.map(&extract_ip/1)
    |> Enum.uniq()
  end

  defp parse_log_line(line) do
    case Regex.run(~r/^(\S+).*HTTP\/\d\.\d" (\d+)/, line) do
      [_, ip, status] -> {ip, String.to_integer(status)}
      _ -> nil
    end
  end

  defp is_error?({_ip, status}) when status >= 500, do: true
  defp is_error?(_), do: false

  defp extract_ip({ip, _status}), do: ip
end

# 実行
LogAnalyzer.extract_error_ips(log_data)
# => ["192.168.1.2"]

データの流れが見えます。川の流れです。


結語──コードは詩である

パイプ演算子 |> は、Elixirの最も美しい機能の一つです。

データが川のように流れ、処理が詩のように連なる。

猪木さんの「道」は、Elixirのパイプラインに通じている。
流れは力を生み、力は再び流れを生む。

迷わず書けよ、書けばわかるさ。 🔥


参考資料


この記事は、Elixirの美しさと猪木さんの哲学を融合させた、闘魂プログラミングの実践です。

元気があれば、何でもできる。コードも書ける。 🔥

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?