Elixir標準モジュールのキャスト関数をリスト化してみた
動機
先日、Twitterで「キャストメソッド/関数はどちらのクラスに生やせば良いのか」という疑問が投げられ、様々な回答が集まっていました。Togetterにもまとめられています。
上記の議論を見て、「Elixirでは、キャスト関数はどういうルールやパターンで実装されているのだろう?」と気になったので、Elixir標準の各モジュールのキャスト関数をリスト化するプログラムを作ってみました。
作ったもの
キャスト関数のリストとソースコードは下記リポジトリに置いてあります。
使用方法
iex> ElixirCastFunction.run
使用ライブラリ
- Floki
- Jason
- Req
仕組み
元となるデータは、HexDocのElixirのページを使いました。
HexDocsのサイドバーに関数のリストがモジュール毎にまとまっていたのでFlokiを使いスクレイピングしました。
誤算だったのは、サイドバーの情報はAjaxで動的に取得されてたので単純にHexDocsのHTMLを分析しても結果が得られなかったことです。
そのため、1度HexDocsのHTMLを取得し、HTMLからサイドバーの情報が記載されたJavaScriptのURLを取得して、改めてJavaScriptにリクエストしています。
その後、JavaScriptからモジュール名と関数名のリストを構築し、マークダウンのテーブルの形式になるよう整形してIO.puts/1
でコンソールに出力させています。
JavaScriptに書かれた情報がリストの入れ子が連続していたため、かなり複雑な取得ロジックになってしまいました。
この部分は後で書き直すつもりです。
TODO
- Mermaidで図を作る
- "DEPRECATED"となっているモジュールをリストから除外する
今後は、関数間のキャストする/されるの関係を分かりやすくするためMermaidを使って図示しようと考えています。
また、非推奨のモジュール(Dict、HashDict、HashDict、Set)の関数もリストに含まれているので、これは除外するつもりです。
このリストが、Elixir開発のお役に立てば幸いです。
2022/02/12 追記
IO.chardata_to_string/1
のように、xxx_to_yyy
の名前のキャスト関数があることに気が付いたので、抽出条件をstarts_with?
からcontains?
に修正してリストを更新しました。
また、touch/2
などキャスト関数でないものがリストに含まれていたので削除しました。
Discussion
面白いですね。一覧で見ると色々あるんだなと参考になります 👍
スクレイピングせずに取るにはどうしたらいいかな?と遊んでみたので共有してみます。
良い勉強になりました、遊ぶ題材をいただきましてありがとうございます🚀
参考: https://elixirforum.com/t/question-on-application-get-key-my-app-module/29391
結果
コメントありがとうございます!
テーマに興味持っていただけて嬉しいです!
モジュール.module_info(:functions)
で取得する関数はプライベート関数も返すんですね(Version.to_matchable/2
など)公開されている関数だけを取得したい場合は、
module_info(:exports)
の方が良さそうでした。書いてもらったコードもfilterやrejectの使い方がスッキリしていて分かりやすいので、実装方法を参考にさせていただきます。