iexで関数のドキュメントを調べる方法 他3本
はじめに
この記事は、Qiitaの「Elixir Advent Calendar 2021」の3日目の記事です。
2日目はtorifukukaiouさんによる「【Elixir】B - FizzBuzz Sum問題をEnum.map/2 |> Enum.filter/2 |> Enum.sum/1, Enum.reduce/3 を使って解く (2021/12/02)」でした。
手続き型言語やオブジェクト指向型言語に慣れ親しんで来た方は、Elixirでの解法に驚いたかも知れませんね。
興味を持った方はぜひElixirへ入門してAlchemistへの一歩を踏み出してみてください。
Elixirで競技プログラミングしたい、Elixirを書きたいから何かお題が欲しい!という方は、昨日より「Advent of Code 2021」が開催されています。
「Advent of Code 2021」はアドベントカレンダーのように12月25日まで問題が1問ずつ出題され、それを解いていく遊びです。
個人的にはテキストベースのシンプルな見た目がお気に入りです。
ElixirのForumサイトでも解法について議論しているようなので参考になると思います。
ぜひ挑戦してみてください。
本題
この記事は「iexで関数のドキュメントを調べる方法 他3本」です。
※ torifukukaiouさんの記事にあるタイトルが違うのは私が急な仕様変更したためです。
1. iexの実行スクリプト
LinuxやMac環境では、$> cat $(which iex)
で実行スクリプトの中身を見ることができます。
環境の都合でcatコマンドを使っていますが、batコマンドがオススメです。
$> cat $(which iex)
#!/bin/sh
set -e
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
cat <<USAGE >&2
Usage: $(basename "$0") [options] [.exs file] [data]
The following options are exclusive to IEx:
--dot-iex "PATH" Overrides default .iex.exs file and uses path instead;
path can be empty, then no file will be loaded
--remsh NAME Connects to a node using a remote shell
It accepts all other options listed by "elixir --help".
USAGE
exit 1
fi
readlink_f () {
cd "$(dirname "$1")" > /dev/null
filename="$(basename "$1")"
if [ -h "$filename" ]; then
readlink_f "$(readlink "$filename")"
else
echo "$(pwd -P)/$filename"
fi
}
SELF=$(readlink_f "$0")
SCRIPT_PATH=$(dirname "$SELF")
exec "$SCRIPT_PATH"/elixir --no-halt --erl "-noshell -user Elixir.IEx.CLI" +iex "$@"
$> elixir --no-halt --erl "-noshell -user Elixir.IEx.CLI"
Erlang/OTP 24 [erts-12.0.3] [source] [64-bit] [smp:4:1] [ds:4:1:10] [async-threads:1] [jit]
Interactive Elixir (1.12.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
2. iexでモジュールから呼び出せる関数を調べる方法 いくつか
A. _info_(:functions)
ドキュメント
> IEx.Helpers.__info__(:functions)
[
break!: 3,
break!: 4,
breaks: 0,
c: 1,
c: 2,
cd: 1,
clear: 0,
continue: 0,
exports: 0,
exports: 1,
flush: 0,
h: 0,
i: 0,
i: 1,
l: 1,
ls: 0,
ls: 1,
nl: 1,
nl: 2,
open: 0,
pid: 1,
pid: 3,
port: 1,
port: 2,
pwd: 0,
r: 1,
recompile: 0,
recompile: 1,
ref: 1,
ref: 4,
remove_breaks: 0,
remove_breaks: 1,
reset_break: 1,
reset_break: 3,
respawn: 0,
runtime_info: 0,
runtime_info: 1,
v: 0,
v: 1,
whereami: 0,
whereami: 1
]
B. module_info/1
ドキュメント(erlang)
> IEx.Helpers.module_info :exports
[
__info__: 1,
"MACRO-b": 2,
"MACRO-break!": 2,
"MACRO-break!": 3,
break!: 3,
break!: 4,
breaks: 0,
c: 1,
c: 2,
cd: 1,
clear: 0,
continue: 0,
exports: 0,
exports: 1,
flush: 0,
h: 0,
"MACRO-h": 2,
i: 0,
i: 1,
"MACRO-import_file": 2,
"MACRO-import_file": 3,
"MACRO-import_file_if_available": 2,
"MACRO-import_if_available": 2,
"MACRO-import_if_available": 3,
l: 1,
ls: 0,
ls: 1,
nl: 1,
nl: 2,
open: 0,
"MACRO-open": 2,
pid: 1,
pid: 3,
port: 1,
port: 2,
pwd: 0,
r: 1,
recompile: 0,
recompile: 1,
ref: 1,
ref: 4,
remove_breaks: 0,
remove_breaks: 1,
reset_break: 1,
reset_break: 3,
respawn: 0,
runtime_info: 0,
runtime_info: 1,
"MACRO-t": 2,
"MACRO-use_if_available": 2,
...
]
C. IEx.Helpers.exports/1
ドキュメント
> exports IEx.Helpers
b/1 break!/1 break!/2
h/1 import_file/1 import_file/2
import_file_if_available/1 import_if_available/1 import_if_available/2
open/1 t/1 use_if_available/1
use_if_available/2 break!/3 break!/4
breaks/0 c/1 c/2
cd/1 clear/0 continue/0
exports/0 exports/1 flush/0
h/0 i/0 i/1
l/1 ls/0 ls/1
nl/1 nl/2 open/0
pid/1 pid/3 port/1
port/2 pwd/0 r/1
recompile/0 recompile/1 ref/1
ref/4 remove_breaks/0 remove_breaks/1
reset_break/1 reset_break/3 respawn/0
runtime_info/0 runtime_info/1 v/0
v/1 whereami/0 whereami/1
3. モジュール情報を取得する方法 いくつか
A. IEx.Helpers.h/1
ドキュメント
> h IEx.Helpers
IEx.Helpers
Welcome to Interactive Elixir. You are currently seeing the documentation for
the module IEx.Helpers which provides many helpers to make Elixir's shell more
joyful to work with.
This message was triggered by invoking the helper h(), usually referred to as
h/0 (since it expects 0 arguments).
You can use the h/1 function to invoke the documentation for any Elixir module
or function:
iex> h(Enum)
iex> h(Enum.map)
iex> h(Enum.reverse/1)
(省略)
B. module_info/0
ドキュメント(erlang)
> IEx.Helpers.module_info
[
module: IEx.Helpers,
exports: [
__info__: 1,
"MACRO-b": 2,
"MACRO-break!": 2,
"MACRO-break!": 3,
break!: 3,
break!: 4,
breaks: 0,
c: 1,
c: 2,
cd: 1,
clear: 0,
continue: 0,
exports: 0,
exports: 1,
flush: 0,
h: 0,
"MACRO-h": 2,
i: 0,
i: 1,
"MACRO-import_file": 2,
"MACRO-import_file": 3,
"MACRO-import_file_if_available": 2,
"MACRO-import_if_available": 2,
"MACRO-import_if_available": 3,
l: 1,
ls: 0,
ls: 1,
nl: 1,
nl: 2,
open: 0,
"MACRO-open": 2,
pid: 1,
pid: 3,
port: 1,
port: 2,
pwd: 0,
r: 1,
recompile: 0,
recompile: 1,
ref: 1,
ref: 4,
remove_breaks: 0,
remove_breaks: 1,
reset_break: 1,
reset_break: 3,
respawn: 0,
runtime_info: 0,
runtime_info: 1,
...
],
attributes: [vsn: [334571827834058247655098702395170864842]],
compile: [
version: '8.0',
options: [:no_spawn_compiler_process, :from_core, :no_core_prepare,
:no_auto_import],
source: '/root/deb/elixir_1.12.0-1/lib/iex/lib/iex/helpers.ex'
],
md5: <<251, 180, 48, 175, 119, 74, 106, 111, 122, 177, 39, 14, 81, 223, 190,
202>>
]
C. IEx.Info.info/1
ドキュメント
内部では、上記のmodule_info
を呼び出しています。
> IEx.Info.info IEx.Helpers
[
{"Data type", "Atom"},
{"Module bytecode",
"/usr/lib/elixir/bin/../lib/iex/ebin/Elixir.IEx.Helpers.beam"},
{"Source", "/root/deb/elixir_1.12.0-1/lib/iex/lib/iex/helpers.ex"},
{"Version", "[334571827834058247655098702395170864842]"},
{"Compile options",
"[:no_spawn_compiler_process, :from_core, :no_core_prepare, :no_auto_import]"},
{"Description",
"Use h(IEx.Helpers) to access its documentation.\nCall IEx.Helpers.module_info() to access metadata."},
{"Raw representation", ":\"Elixir.IEx.Helpers\""},
{"Reference modules", "Module, Atom"}
]
4. 関数のドキュメントを表示する方法 いくつか
A. IEx.Helpers.h/1
ドキュメント
> h IEx.Helpers.h
def h()
Prints the documentation for IEx.Helpers.
defmacro h(term)
Prints the documentation for the given module or for the given function/arity
pair.
## Examples
iex> h(Enum)
It also accepts functions in the format function/arity and
module.function/arity, for example:
iex> h(receive/1)
iex> h(Enum.all?/2)
iex> h(Enum.all?)
B. IEx.Introspection.h/2
ソースコード(なぜかHexDocで見当たらない)
> IEx.Introspection.h {IEx.Helpers, :h}
def h()
Prints the documentation for IEx.Helpers.
defmacro h(term)
Prints the documentation for the given module or for the given function/arity
pair.
## Examples
iex> h(Enum)
It also accepts functions in the format function/arity and
module.function/arity, for example:
iex> h(receive/1)
iex> h(Enum.all?/2)
iex> h(Enum.all?)
おわり
iexの機能を使うことで、ブラウザでドキュメントを探す手間を省いたり、ドキュメントに載っていない関数を探したり、ソースコードの場所を調べることができます。
他にもiexにはさまざまな機能がありますので、気になった方は下記のディレクトリの中を探索してみると面白いと思います。
明日は、takasehidekiさんによる「仏像さんに触発されてElixirをビルドしてみた」です。
お楽しみに。
おまけ
もとより予定していた「"phx.server"コマンドの実装を追い掛ける」はfukuoka.exさんのAdeventCalendarで投稿予定です。
Discussion