白露に風の吹きしく秋の野はつらぬきとめぬ玉ぞ散りける
Advent Calendar 2022 88日目1の記事です。
I'm looking forward to 12/25,2022
私のAdvent Calendar 2022 一覧。
はじめに
Elixirを楽しんでいますか
My Advent Calendar 2022 goes behind 8 days.
NP.
is_number/1を読んでみます。
is_xxx Guards
あるterm
があったときにそれが何であるのかを判定するGuardsと呼ばれるものがあります。
is_
という接頭辞で始まります。
以下のものがあります。
たとえば、is_atom/1は、term
がAtomである場合にtrue
、それ以外の場合にはfalse
が返ります。
- is_atom/1
- is_binary/1
- is_bitstring/1
- is_boolean/1
- is_exception/1
- is_exception/2
- is_float/1
- is_function/1
- is_function/2
- is_integer/1
- is_list/1
- is_map/1
- is_map_key/2
- is_nil/1
- is_number/1
- is_pid/1
- is_port/1
- is_reference/1
- is_struct/1
- is_struct/2
- is_tuple/1
is_number/1
上記の中で、is_number/1は、term
が整数やFloatである場合にtrue
、それ以外の場合にはfalse
が返ります。
どういうふうに実装されているのだろうと気になりました。
気になったものは仕方ありません。
人間の好奇心は誰にも止められません。
もう少し言葉にしてみると、ある変数を宣言するときにElixirでは型とともに宣言しないので、型がなにであるかを確かめるのは結構複雑なことをしないとわからないのではないかとおもいました。
複雑なElixirの実装に出会えるのではないかとワクワクドキドキしました。
はたしていかに
調べたことは、Qiitaに書いておきます。
[</>]
を押してみます
is_number/1のドキュメントに行きます。
[</>]
のリンクを押してみましょう。
迷わず押せよ!
押せばわかるさ!
ありがとう!
def is_number(term) do
:erlang.is_number(term)
end
ほうほう、たったのこれだけでした。
Erlangのis_number
を呼び出していました。
Erlangのis_number
Erlangに深入りしてみます。
%% Shadowed by erl_bif_types: erlang:is_number/1
-spec is_number(Term) -> boolean() when
Term :: term().
is_number(_Term) ->
erlang:nif_error(undefined).
最後はCで実装されているようです。
断片だけ示しておきます。
ちゃんと追えているのかあんまり自信はありません。
#define is_number(x) (is_integer(x) || is_float(x))
ここからは、is_integer
のほうに進んでみます。
#define is_integer(x) (is_small(x) || is_big(x))
また ||
になっています。
ここからは、is_small
のほうに進んでみます。
#define is_small(x) (((x) & _TAG_IMMED1_MASK) == _TAG_IMMED1_SMALL)
#define _TAG_IMMED1_MASK 0xF
#define _TAG_IMMED1_SMALL ((0x3 << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_IMMED1)
調べ方は、Erlangのリポジトリで、左上のSearch or jump to...
にキーワードを打ち込んで、でてきた結果を眺めました。
並べました。
Wrapping up
Enjoy Elixir
$\huge{Enjoy\ Elixir🚀}$
is_number/1の実装を追いかけてみました。
Erlangのis_number
を呼び出しているだけでした。
Erlangに入ってからは、ちゃんと追いかけられているかどうかはあんまり自信はありません。
以上です。