💭

Elixirで自動化ツール作ってみた【はじめてのElixir】

2024/09/10に公開

最近仕事で多くの画像を変換する作業があり、だるいなあー、ツール作るかーと思いまして、以前から気になっていたElixirを勉強してみることにしました。そしてelixirをさわった感想をまとめました。

今回作ったのはこちら↓
https://github.com/dev-komenzar/avifixir

作りたかったもの

  • 指定されたディレクトリsrc以下にある.avif画像を一括で.jpgに変換したかった。.avifは古い端末で表示できないため。
  • 指定されたディレクトリdist.jpg画像を作る。その際src以下にあるサブディレクトリを再現する。
  • ex. src/sample/image.avif -> dist/sample/image.avif

やったこと

Elixir Schollで勉強。初級と一部使いそうな記事を読みました。
https://elixirschool.com/ja
画像変換の部分をどうしようか探していると、ImageMagickのラッパーライブラリmogrifyを見つけました。これをコマンドラインから使えるようにしてみました。

Elixirをさわってみて感じたこと

関数型言語の書き心地よき

私は関数型言語にそこまで詳しくなく「大学の授業でラムダ計算ってあったけど意味不明やったな」という感じでした。フロントがメインなので「js/tsで.mapとか.reduceとか使うのは便利だ」と感じていましたね。

今回elixirを使ってみて「関数型、ええやん」と感じたところは、

  • すべて式
    • =とかifも文でなくて式だった!
  • パターンマッチ
  • パイプライン演算子

とくにパイプラインはめちゃくちゃ気持ちよくコードが書けます。たとえばいくつもの処理を続けていく場合jsだと次のように書きます。

const a = functionA("sample")
const b = functionB(a)
const c = functionC(c)

このように1回しか使わない変数をたくさん用意しなければならず、命名もめんどくさいです。一方パイプラインがあれば次のように書けます。

c =  "sample"
    |> function_a()
    |> function_b()
    |> function_c()

3つの処理が終わった結果を変数に格納できるのが非常に便利ですし、コードの閲覧性も高い気がします。

ただコード中のカッコについては気になりました。なんとなく関数型ではカッコを省略して書くもんだと思ってたのですが、elixirではあまりカッコを省略しないんですね。自動フォーマットするとカッコをつけるように修正される場合が多かったです。カッコの省略する場所によってはパースエラーが起こります。コミュニティのスタイルガイドにケース例があります。

https://github.com/kenichirow/elixir_style_guide/blob/master/README-jaJP.md#L1

型がなかったのか!(動的型付け言語)

elixirはじわじわと人気があると思っているのですが、人気がある言語は静的型付けだと勝手に思い込んでいました。実際にコードを書き始めると「あれ、型がない…」とびっくりしました。ほんと、勝手に思い込んでいただけなんですが。「関数型=流行の最先端=型がある」ていう先入観。

Elixir Schoolを進めると上級編に仕様と型というページがありました。@specアノテーションを書くことでコンパイラに関数の仕様をつたえることができるそうです。そして型は@typeアノテーションで定義します。ここで定義した独自の型は@specに記述できます。

ということはコード本体の方には型の情報はつたわってないんか。jsと同じような動的型付け言語として、厳密な型を利用したコードを書くよりスピード感のある開発に向いているのかな。

型も関数なのはおもしろかったです。もうちょっと理論的なところを学びたいですね。

@specwhen is_***のちがい

こちらも型と近い話です。勉強しているとき、関数の仕様@specと引数のガードwhen is_***節の違いがよくわかりませんでした。

「型を指定できるならガードの意味って?」
「型をガードで使おうとしたらエラーになった!なぜ?」

こんなふうに混乱してしまいました。これらは結局elixirが動的言語であることを考えれば解決しました。

  • ガードはプログラム実行時、関数が呼び出されるときに引数に対してテストするもの。
  • 対して、@specDialyzerのようなプログラム実行以前に静的に型チェックするツールで利用するもの。

@specで書いた仕様をツールがチェックするというのは、jsでいうならjsdocで記述して// @ts-checkを先頭に書いておけばtsコンパイラがチェックしてくれるようなものでしょうか。

結局@specとガード節は評価するタイミングが違うということでした。elixirは動的言語と考えてガードでざっくりとバグをはじく設計になっているのですね。

公式ツールが充実している

フロントエンド界隈ではリンター、フォーマッターが乱立してます。テストツールもたくさんあり、バンドラーもさまざまです。その点elixirは公式ツールが充実しているのが魅力でした。

  • テストツール ExUnit
  • スタイルガイドが決まっているので宗教戦争にならない
    • コミュニティ主導で開発
    • PRを受け付けている
  • ドキュメント生成→公開 ExDoc
  • その他たくさん

ツールが定まっているので、初心者が調べてもわかりやすかったです。フロントではツールの開発が盛んな一方で、読んでいる記事が今では役に立たないなど困ることも多いです。

参考になったサイト

最後に参考にしたサイトを紹介します。

基本的な勉強はElixir School
https://elixirschool.com/ja

公式リファレンス
基本的な型の定義を見ました。またPathFileなど基本的なモジュールの説明も参考にしました。
https://hexdocs.pm/elixir/typespecs.html

ExDoc
プロジェクトの構成やコードの書き方を参考にしました。
https://github.com/elixir-lang/ex_doc

勉強の全体的に天秤.aiを使用しました。

Discussion