VimでElixirする
Gleamを触ってみたけど、まだまだ発展途上のプロジェクトで実用的なプロジェクトを作るのは厳しそうなので先にElixirでなんか作って体を慣らしておきたい
LSPはMasonを使ってる場合、MasonInstall elixir-ls
した後にlsが格納されているディレクトリを指定する
Linux(WSL)の場合は以下の通り。
if server == "elixirls" then
require("lspconfig").elixirls.setup({
-- Unix
cmd = { "/home/coma/.local/share/nvim/mason/bin/elixir-ls" },
})
end
以下参照元のGist(手前味噌)
Gistにも書いてあるけど、これだけだとハイライトが効かないので別途ハイライト用のプラグインを入れる必要がある
とりあえずインストールも環境構築も完了したので、早速ゴリッゴリに書いていきたいのだけれど実行方法が分からん。調べた感じ色々あるらしい。
Goとかを書いているので、go run .
みたいな感じで実行できるとありがたいのだけれど、それっぽいmix run
を実行してもなぜか実行されない。
Elixirには.ex
と.exs
という二通りの形式があるらしく、
- exはコンパイルするファイル
- exsはインタプリタで実行可能なファイル(コンパイルが不要。設定ファイルとして使われてる場合が多い)
という違いがあるらしい。mix run
で/lib
配下に.ex
ファイルがある場合はコンパイルしかされない...という解釈で良いのだろうか
escriptというものを使うと良い感じに実行できるらしい。
まずmix new
で生成されるlib/
配下のex
ファイルにあるdefmodule
内にmain関数を作成する。この時引数でコマンドライン引数を受け取れるようにしなければいけないらしい。よく分かんなかったので以下の通りに実装してみた。_を使うと入力を切り捨てる事ができる。これは慣例的なのでわかりやすい。
# defmodule内に実装する
def main(_args // []) do
IO.puts("Hi Elixir!")
end
次に mix.exs
を編集する。差分は以下の通り
defmodule ElixirWebsocket.MixProject do
use Mix.Project
def project do
[
app: :elixir_websocket,
version: "0.1.0",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
# ElixirWebsocketはプロジェクトmain関数を追加したモジュールの名前
+ escript: [main_module: ElixirWebsocket],
deps: deps()
]
end
end
以下実行したコマンド
mix escript.build
# 配下に実行ファイルが生成される
./elixir_websocket
# main関数内の処理が実行される
とりあえずMisskeyのストリームAPIにアクセスするために、投稿するようのJsonを書いている。
def jsn do
payload: %{
type: "connect",
body: %{
channel: "main", #ここでエラーが発生する
id: "foobar",
},
}
このようにしてJsonに当たるMapの表現ができる。再帰的にMapを定義する場合は、そのMapにも%
をつけないと構文エラーになるらしい。これでかなりハマったので注意
こっちのほうがなんか良い感じに書けそうなのでこっちで書いてみる。
Websocket以外の通信方式にも対応してるので、Elixirで通信処理を書くならこれが一番良いのかな
どうやらライブラリのAPIに対する考え方がかなり違ったらしい...
callbackを指定して処理を記述させていくと、呼び出し処理なんかを省けて良い感じに書けるのでこれが関数型言語の流儀なのかな...なんて思っている
WebSocketはハードルが高かったので、まずは適当なエントリポイントを叩くことにする。
Misskey APIを参考に、自分のアカウント情報を取得してみる。
できた。リプにもソースコード貼ってるけどこっちにも。
endpoint = "https://#{host}/api/i"
body = %{
i: token
}
resp =
HTTPoison.post!(endpoint, Jason.encode!(body), %{
"Content-Type" => "application/json"
})
json = Jason.decode!(resp.body)
IO.puts("#{json["name"]}@#{json["username"]}")
IO.puts(json["description"])