Slide 1

Slide 1 text

Hack and Read Elixir 2021-11-20 tokyo.ex Reboot

Slide 2

Slide 2 text

agenda ● About Me ● ゴール ● モチベーション ● リポジトリ ● ディレクトリ構造 ● ビルドの全体構造 ● コマンドの実体 ● ソースコードのエントリーポイント ● まとめ

Slide 3

Slide 3 text

About Me ● おーはら / Twitter: @ohrdev / Github: ohr486 ● 株式会社ドリコム SRE部 部長 ○ Work: ■ エンジニアマネージャ ● 技術戦略の策定/推進 ● エンジニア採用/採用戦略策定 ■ サーバー/インフラエンジニア ● 開発現場でゲームのバックエンド (Rails/Phoenix/Go/HCL)のコード書いてます ■ 新規事業/ディレクター ● 負荷試験支援/DevOps推進支援/設計コンサル ● Community ○ tokyo.ex / Japan Elixir Association / Erlang&Elixir Fest ● Hobby ○ 仏像制作 ○ 自転車

Slide 4

Slide 4 text

ゴール ● ターゲット ○ elixir言語のコードを理解したい人 ○ elixirにコントリビュートしたい人 ○ elixir言語を改造したい人 ● 今日のゴール ○ elixir言語の全体概要を理解する ○ github/elixir-lang/elixir のリポジトリの構成を理解する ○ elixir言語のソースコードを読むためのエントリーポイントを作る

Slide 5

Slide 5 text

モチベーション ● elixir言語自体の把握の仕方のドキュメントが少ない ○ 日本語のドキュメントはほぼ無い ● elixir本体のissue/PRを読む時に、elixir言語の全体構成を知っておけば捗るシチュ エーションが結構ある ○ 全体構成を知らなくても issue/PRを理解できる場合もあるが、コントリビュートする際は絶対知って おいた方が良い

Slide 6

Slide 6 text

リポジトリ ● https://github.com/elixir-lang/elixir ○ issue: https://github.com/elixir-lang/elixir/issues ○ PR: https://github.com/elixir-lang/elixir/pulls ● 特徴: issue/PRの取り込み/消化スピードが早い ○ joseがすごい勢いで取り込んでいく ○ issue/PRがだいたい常に1ページに収まっているのでは ● Code of Conduct ○ https://github.com/elixir-lang/elixir/blob/main/CODE_OF_CONDUCT.md ○ github/メーリングリスト/IRC上での振る舞いの指針 ○ コントリビュートする前に目を通すべし ● (注意) メインブランチが master -> main に変更された ○ 既にリポジトリをforkしている人は注意してください

Slide 7

Slide 7 text

ディレクトリ構造 ● 重要なディレクトリ/ファイル ○ Makefile ■ 言語本体のビルド/コンパイルの起点 ○ VERSION ■ 言語本体のコンパイル時に参照されるバージョンを記載 ○ bin/ ■ elixirの各種コマンドの実行ファイル ● elixir, elixirc, iex, mix ■ 実体はErlangのerlコマンドを起動するシェルスクリプト ○ lib/ ■ elixir本体と関連ツール/ライブラリのソースコード ■ erlangとelixirのソースコードから構成される ● eex, elixir, ex_unit, iex, logger, mix

Slide 8

Slide 8 text

ビルドの全体構造(tokyo.ex #13 elixirコードリーディング会) ● https://speakerdeck.com/ohr486/hacking-elixir-how-to?slide=10

Slide 9

Slide 9 text

ビルドの全体構造 make make erlang elixir.app make elixir ビルド時の起点 yeccを使ってパーサーコードを lib/elixir/src/elixir_parser.erlとして生成 erl -makeでlib/elixir/src以下のerlangコードをcompile -> lib/elixir/Emakefileを読み込み make:all() を実行している -> コンパイルにより lib/elixir/ebin以下に*.beamファイルが生成される lib/elixir/generate_app.escriptでlib/elixir/ebin/elixir.appを生成 -> elixir.appはerlangのアプリケーション・リソースファイル Elixir.Kernel.beam make erlangで生成されたelixir_compilerモジュールのbootstrap関数を call -> $(ERL) -s elixir_compiler bootstrap -s erlang halt -> erl -s ... => Mod:Func(Arg1,...)を実行 -> elixir_compiler:bootstrapを実行して、erlang:haltで終了 mix,ex_unit logger,eex,iex MakefileのAPP_TEMPLATEの定義から標準ライブラリをコンパイル -> 各ディレクトリ内で、 elixircによるコンパイル 赤太字: erlangの機能

Slide 10

Slide 10 text

コマンドの実体 ● bin配下のシェルスクリプト(windowsの場合は.batファイル) ○ elixir / elixirc / iex / mix ● コマンドの依存関係 elixirc elixir iex mix +elixir オプションを付けて exec elixir 以下のオプションを付けて exec elixir --no-halt --erl “-noshell -user Elixir.IEx.CLI” +iex #!/usr/bin/env elixir Mix.start() Mix.CLI.main() 実体はerlコマンド elixirに渡されるオプションから erlに渡す引数を調整 例) +iexオプションがついていない時 erlの起動オプションに、 -noshell -s elixir start_cli を付与して から実行する erlコマンド実行時の内容を知りたい時は、 ELIXIR_CLI_DRY_RUN=1 を指定すれば内容を確認できる

Slide 11

Slide 11 text

コマンドの実体(elixir) ELIXIR_CLI_DRY_RUN=1 elixir --version erl -pa /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/eex/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/elixir/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/ex_unit/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/iex/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/logger/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/mix/ebin -elixir ansi_enabled true -noshell -s elixir start_cli -extra --version [オプション] -pa: 後ろに続くディレクトリ配下のモジュールを erl実行時にロード -noshell: erlangの対話シェルを起動せずに erlを実行 -s : ModモジュールのFunc関数を実行 elixir:start_cli() https://github.com/elixir-lang/elixir/blob/main/lib/elixir/src/elixir.erl

Slide 12

Slide 12 text

コマンドの実体(iex) ELIXIR_CLI_DRY_RUN=1 iex erl -pa /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/eex/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/elixir/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/ex_unit/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/iex/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/logger/ebin /Users/ohara_tsunenori/.asdf/installs/elixir/1.12.3/bin/../lib/mix/ebin -elixir ansi_enabled true -noshell -user Elixir.IEx.CLI -extra --no-halt +iex [オプション] -pa: 後ろに続くディレクトリ配下のモジュールを erl実行時にロード -noshell: erlangの対話シェルを起動せずに erlを実行 IEx.CLI https://github.com/elixir-lang/elixir/blob/main/lib/iex/lib/iex/cli.ex

Slide 13

Slide 13 text

ソースコードのエントリーポイント ● elixirのビルドを理解したい ○ Makefile: ■ https://github.com/elixir-lang/elixir/blob/main/Makefile ● 標準ライブラリを理解したい ○ lib/*/mix.exs ■ eex, ex_unit, iex, logger, mix ■ mixプロジェクトの形式で提供される

Slide 14

Slide 14 text

ソースコードのエントリーポイント ● elixirのコンパイラを理解したい ○ パーサー: ■ https://github.com/elixir-lang/elixir/blob/main/lib/elixir/src/elixir_parser.yrl ○ コンパイラ(bootstrap関数): ■ https://github.com/elixir-lang/elixir/blob/main/lib/elixir/src/elixir_compiler.erl ○ ※一般的なプログラム言語のコンパイルの基礎知識は事前にあったほうが良い ■ ソースコード > 字句解析 > 構文解析 > 意味解析 ○ ※ErlangのAST/AbstractFormatの知識は事前にあったほうが良い ● elixirのプログラム実行時の処理について理解したい ○ elixirコマンドの起動モジュール(start_cli): ■ https://github.com/elixir-lang/elixir/blob/main/lib/elixir/src/elixir.erl ○ プロセス構造(elixir_sup): ■ https://github.com/elixir-lang/elixir/blob/main/lib/elixir/src/elixir_sup.erl ■ elixir:start_cli()実行時に elixir_sup:start_link() される

Slide 15

Slide 15 text

まとめ ● elixirのリポジトリの構造について紹介しました ● elixirのビルド時の処理について紹介しました ○ elixirのコンパイラはerlangで実装されている事を紹介しました ● elixir, elixirc, iex, mixコマンドの実体について紹介しました ● elixir本体のコードリーディングの起点について紹介しました