14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

感動したPull Request: Elixirにおけるテスト,リファクタリング,ドキュメント,PRの書き方のお手本

Last updated at Posted at 2023-07-03

Pelemay Backendという Apache 2.0 License のOSSを開発しています.最初の小さなリリース に向けて鋭意開発を進めています. は2023年7月6日にできました!

このPelemay Backendのコンセプトは次の記事にまとめています.

一言で言うと,次のようなものです.

PelemayBackend: A memory-saving, fault-tolerant and distributed collection of Nx compilers and backends for embedded systems.
PelemayBackend: 組込みシステム用の Nx コンパイラとバックエンドの省メモリフォールトトレラント分散型コレクション

今は @mnishiguchi さんと一緒に開発を進めています.

ElixirのIoTフレームワークである,Nerves Projectのコアメンバーの1人です.

はじめてZoomでお話しして,Pelemay Backendの開発にお招きしたときに, @mnishiguchi さんは謙遜だと思うのですが,「私はプログラミングは苦手で,テストとドキュメントくらいしか書けない」というような趣旨のことをおっしゃっていました.

しかし,本日いただいたPull Requestを見て,私は驚嘆しました.

これは,テスト,リファクタリング,ドキュメント,PRの書き方のお手本にしたいPRだったのです! これで,プログラミングが苦手って,謙遜も謙遜,なかなかここまで書ける人いないと思いますよ.

この記事では,このお手本PRについて,私の視点で解説していきたいです.

PR の SubjectとDescriptionが簡潔ながら要点を得ていて,とても読みやすい!

まず目が行くのが,SubjectとDescriptionです.

refactor(NodeActivator): split module #146

Description

  • factor out sub-modules
    • Epmd
    • Utils
  • add module document for the top-level module
  • add function documents

Notes

The sub-modules are private (@moduledoc false) as of now. Only the top-level module will show in the Hex document.

うーん美しい.このPRの目的と意図が明確に書かれていて,あとで読み返したときに意思決定や思想,文化を理解するのに十分な情報です.

思い切ったリファクタリングの方針

次に,先ほどのDescriptionの記述を見返しながら,具体的にどのような変更を加えたのか見てみましょう.

リファクタリングの方針として,メインモジュールである NodeActivatorには,思い切って run関数のみを置いています.start_distributed_node関数は,defpと書いてあるように,プライベート関数なので,公開した時のドキュメントに記載されることはありません.

mix docs コマンドで生成されるNodeActivatorモジュールのドキュメントを見てみると,次のようにシンプルです.

Docs of NodeActivator

ごちゃごちゃ定義されていた関数群は,サブモジュールEpmdUtilsに機能的に分類されて配置されています.しかも,これらのサブモジュールについて,@moduledoc falseを指定することで,ドキュメントを生成しないように隠蔽しています.

的確なドキュメント

次に,@docに書かれたrun関数の説明を見てみましょう.

run(node_name_prefix)
@spec run(binary()) :: {:ok, node()} | {:error, any()}

Turns a non-distributed node into a distributed node after ensuring that the epmd operation system process is running. Returns the name of the started distributed node. The node name will be generated by appending a random string to the provided node_name_prefix string.

This function does nothing when the distribution has already been started.

For more info, see Node.

Examples

{:ok, node_name} = NodeActivator.run("foo")

あえて,Google翻訳での日本語訳をそのまま載せます.

epmd オペレーティング システム プロセスが実行されていることを確認した後、非分散ノードを分散ノードに切り替えます。 開始された分散ノードの名前を返します。 ノード名は、指定された node_name_prefix 文字列にランダムな文字列を追加することによって生成されます。

すでに配信が開始されている場合、この関数は何も行いません。

詳細については、ノード を参照してください。

誤訳がほぼないですね.ErlangやElixirに慣れていない人にとっては,epmdが何なのか,という点だけわからないと思いますが,それ以外については,どういう条件の時に何を行うのか,何を返すのかが明確です.また,引数にnode_name_prefixと命名しているのもポイント高いです.これにより,この文字列を接頭辞(prefix)として用いてノードを命名することが明らかです.

Examplesに載せているコード例に,iexをつけないことで,doctestとしてではなく,単なるサンプルコードとして見せている点にも注目です.こうすることで,実行するたびに毎回結果が異なるような,doctestに不向きのコード例を載せることができます.

テストの機能的な分類

次にテストコードを見てみましょう.

describeで機能面での分類を,testでそれぞれの機能に対するテストケースを記述しています.それぞれに書かれている名前も要点を簡潔に記述しています.Elixirにおけるテストケースの見本になっています.

assert の対義語である refuteをうまく使っています.refuteを使わないと,例えば,次のように書いてしまいがちなところです.

    test "generates unique atom" do
      node_name1 = Utils.generate_node_name("test prefix")
      node_name2 = Utils.generate_node_name("test prefix")

      assert is_atom(node_name1)
      assert node_name1 != node_name2
    end

しかし,refuteを使って次のように書くのが推奨です.

    test "generates unique atom" do
      node_name1 = Utils.generate_node_name("test prefix")
      node_name2 = Utils.generate_node_name("test prefix")

      assert is_atom(node_name1)
      refute node_name1 == node_name2
    end

おわりに

Elixir中級者の人は,以上のようなポイントを押さえて,テスト,リファクタリング,ドキュメント,PRを書くと良いと思います.

@mnishiguchi さんがNervesコアメンバーに入っていることの理由の1つが,またひとつ,明らかになりました.

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?