├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── README-jaJP.md
├── README.md
├── Rakefile
└── mix.exs
/.gitignore:
--------------------------------------------------------------------------------
1 | _build
2 | deps
3 | doc
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: ruby
4 |
5 | rvm:
6 | - 2.3.0
7 |
8 | install:
9 | - gem install mdl rake
10 |
11 | script:
12 | - rake test
13 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to the Elixir Style Guide
2 |
3 | First of all, thanks for wanting to contribute! :heart:
4 |
5 | You can contribute in several ways:
6 |
7 | * open up an issue if you find something plain old wrong in the style guide
8 | (e.g., typos or formatting);
9 | * open up an issue if you find inconsistencies in the style guide. This way, we
10 | can discuss the better way to eliminate those inconsistencies;
11 | * if you have any suggestions or opinions, open up an issue or (even better!) a
12 | pull request.
13 |
14 | If you edit the `README.md` file, please stick to this set of
15 | formatting/markup/style rules so that the style remains consistent:
16 |
17 | * don't make lines longer than 80 characters (most editors have an auto-wrapping
18 | functionality, for example [Emacs][Emacs LineWrap] or [Vim][Vim word wrap]);
19 | * use reference-style links, like `[an example][Example]`. Put the links in
20 | alphabetical order at the end of the document, and capitalize the first word
21 | of the link label.
22 |
23 | Use Ruby and [Markdownlint] to check your changes:
24 |
25 | ```sh
26 | gem install mdl rake
27 | rake test
28 | ```
29 |
30 | **IMPORTANT**: By submitting a patch, you agree that your work will be
31 | licensed under the license used by the project.
32 |
33 | ## The Project Board
34 |
35 | If you are looking for issues to work on, the [project board][Project KanBan]
36 | is the place to go. Usually, you look at the issues from right to left, as
37 | the ones in the rightmost part are the closer to get merged and have higher
38 | priority.
39 |
40 | If you just want to dive in and start writing, the backlog has the
41 | 'ready to be picked up' issues. These issues have been discussed already and
42 | are most likely just waiting for someone to make a PR. Just look for the
43 | issues with the `enhancement` and/or `help wanted` labels.
44 |
45 | ## Collaborators
46 |
47 | If you have contributed to the repository you can be appointed as a collaborator
48 | after submitting a change and getting it merged. Collaborators are invited to
49 | manage issues, make corrections to the style guide, review pull requests, and
50 | merge approved changes.
51 |
52 | 1. All changes must pass automatic checks before being merged.
53 | 1. Minor changes and corrections can be merged without review.
54 | 1. Significant changes or new style rules should be discussed and approved in a
55 | pull request.
56 |
57 | ## Translations
58 |
59 | If you would like to help translate the Style Guide, check if there is
60 | an [existing translation][Translations] to contribute to. To create a new
61 | translation:
62 |
63 | 1. [Fork] this repository.
64 | 1. Clone your fork locally.
65 | 1. Copy `README.md` to a new file named after the country/language, like
66 | `README-jaJP.md`, and commit your translations there.
67 | 1. Add the main [repo][Repo] as an upstream remote, to fetch and merge changes.
68 |
69 |
70 | [Emacs LineWrap]: http://emacswiki.org/emacs/LineWrap
71 | [Fork]: https://github.com/christopheradams/elixir_style_guide#fork-destination-box
72 | [Markdownlint]: https://github.com/mivok/markdownlint
73 | [Project KanBan]: https://github.com/christopheradams/elixir_style_guide/projects/1
74 | [Repo]: https://github.com/christopheradams/elixir_style_guide.git
75 | [Translations]: README.md#translations
76 | [Vim word wrap]: http://vim.wikia.com/wiki/Automatic_word_wrapping
77 |
--------------------------------------------------------------------------------
/README-jaJP.md:
--------------------------------------------------------------------------------
1 | # [The Elixir Style Guide][Elixir Style Guide]
2 |
3 |
4 | ## 目次
5 |
6 | * __[はじめに](#はじめに)__
7 | * __[このガイドについて](#このガイドについて)__
8 | * [ソースコードレイアウト](#ソースコードレイアウト)
9 | * [構文](#構文)
10 | * [命名](#命名)
11 | * [コメント](#コメント)
12 | * [注釈](#注釈)
13 | * [モジュール](#モジュール)
14 | * [ドキュメント](#ドキュメント)
15 | * [Typespecs](#typespecs)
16 | * [構造体](#構造体)
17 | * [例外](#例外)
18 | * [コレクション](#コレクション)
19 | * [文字列](#文字列)
20 | * _正規表現_
21 | * [メタプログラミング](#メタプログラミング)
22 | * [その他のスタイル](#その他のスタイル)
23 | * [スタイルガイド](#スタイルガイド)
24 | * [ツール](#ツール)
25 | * __[コミュニティへの参加方法](#コミュニティへの参加方法)__
26 | * [コントリビュート](#コントリビュート)
27 | * [広めてください](#広めてください)
28 | * __[コピーライト](#コピーライト)__
29 | * [ライセンス](#ライセンス)
30 | * [帰属](#帰属)
31 |
32 |
33 | ## はじめに
34 | > まるでジャズみたいに一緒に即興で演奏するんだ。
35 | > 私が何かを作って、彼らも何かを作ることで答える
36 |
37 | > -フランク・ゲーリー
38 |
39 | スタイルは重要です。 [Elixir] には実に様々なスタイルがありますが、他の言語と同じように無視されがちです。
40 | スタイルを尊重しましょう。
41 |
42 |
43 | ## このガイドについて
44 |
45 | これは、プログラミング言語 [Elixir] のコミュニティスタイルガイドを作ろうという試みです。気軽にプルリクエストを送ってください。
46 | 実際より5倍も長生きしている言語のようにElixirのコミュニティを活発にしましょう。
47 |
48 | もし他に貢献できるプロジェクトを探しているなら[Hex package manager site][Hex]を見てみてください。
49 |
50 |
51 | このガイドは以下の言語にも翻訳されています。
52 |
53 | * [Chinese Traditional]
54 | * [Japanese]
55 | * [Korean]
56 |
57 | ### ソースコードのレイアウト
58 |
59 |
60 |
61 | *
62 | インデントは **スペース** 2つ。ハードタブは使わないこと。
63 |
64 | [[link](#spaces-indentation)]
65 |
66 | ```elixir
67 | # 悪い例 - スペースが4つ
68 | def some_function do
69 | do_something
70 | end
71 |
72 | # 良い例
73 | def some_function do
74 | do_something
75 | end
76 | ```
77 |
78 | *
79 | Unixスタイルの改行コードを使うこと (\*BSD/Solaris/Linux/OSX ではこれがデフォルトです。Windowsを使っている場合は気をつけてください)
80 | [[link](#line-endings)]
81 |
82 | *
83 | Gitを使っている場合はWindowsの改行コードであなたのプロジェクトがめちゃくちゃになるのを防ぐために、このように設定してください。
84 | [[link](#autocrlf)]
85 |
86 | ```sh
87 | git config --global core.autocrlf true
88 | ```
89 |
90 | *
91 | - オペレータの前後、カンマ、コロン、セミコロンの後にはスペースを入れてください。
92 | - ()や[]の間にはスペースを入れないでください。
93 | - Elixirの処理系にとって空白にほとんど意味はありませんが、コードを読みやすくするためには重要です。
94 | [[link](#spaces)]
95 |
96 | ```elixir
97 | sum = 1 + 2
98 | {a, b} = {2, 3}
99 | Enum.map(["one", <<"two">>, "three"], fn num -> IO.puts num end)
100 | ```
101 |
102 | *
103 | `def`の間や関数内のロジックの区切りに空白行を入れてください。
104 | [[link](#def-spacing)]
105 |
106 | ```elixir
107 | def some_function(some_data) do
108 | altered_data = Module.function(data)
109 | end
110 |
111 | def some_function do
112 | result
113 | end
114 |
115 | def some_other_function do
116 | another_result
117 | end
118 |
119 | def a_longer_function do
120 | one
121 | two
122 |
123 | three
124 | four
125 | end
126 | ```
127 |
128 | *
129 | 関数節に一行の`def`があるならまとめて定義してしまってもよい。
130 | [[link](#single-line-defs)]
131 |
132 | ```elixir
133 | def some_function(nil), do: {:err, "No Value"}
134 | def some_function([]), do: :ok
135 | def some_function([first|rest]) do
136 | some_function(rest)
137 | end
138 | ```
139 |
140 | *
141 | `do:`を使った関数定義が長くなった場合は、改行後インデントしてから`do:`を入れてください。
142 | [[link](#long-dos)]
143 |
144 | ```elixir
145 | def some_function(args),
146 | do: Enum.map(args, fn(arg) -> arg <> " is on a very long line!" end)
147 | ```
148 |
149 | 上記の規約を使用した関数節があり、かつ他に`do:`を使った関数節がある場合は
150 | すべての関数節で改行してから `do:`を入れてください:
151 |
152 | ```elixir
153 | # 悪い例
154 | def some_function([]), do: :empty
155 | def some_function(_),
156 | do: :very_long_line_here
157 |
158 | # 良い例
159 | def some_function([]),
160 | do: :empty
161 | def some_function(_),
162 | do: :very_long_line_here
163 | ```
164 |
165 | *
166 | 複数行の関数節が一つ以上ある場合は一行の`def`を使わないこと。
167 | [[link](#multiple-function-defs)]
168 |
169 | ```elixir
170 | def some_function(nil) do
171 | {:err, "No Value"}
172 | end
173 |
174 | def some_function([]) do
175 | :ok
176 | end
177 |
178 | def some_function([first|rest]) do
179 | some_function(rest)
180 | end
181 |
182 | def some_function([first|rest], opts) do
183 | some_function(rest, opts)
184 | end
185 | ```
186 |
187 | *
188 | 関数のチェインにはパイプライン演算子を使ってください。
189 | [[link](#pipe-operator)]
190 |
191 | ```elixir
192 | # 悪い例
193 | String.strip(String.downcase(some_string))
194 |
195 | # 良い例
196 | some_string |> String.downcase |> String.strip
197 |
198 | # 複数行のパイプラインはインデントしないこと。
199 | some_string
200 | |> String.downcase
201 | |> String.strip
202 |
203 | # パターンマッチの右辺として複数行のパイプラインを使う場合は改行してから書くこと。
204 | sanitized_string =
205 | some_string
206 | |> String.downcase
207 | |> String.strip
208 | ```
209 |
210 | これは好ましい書き方ですが少し注意が必要です。
211 | IExが次の行にパイプラインがあることを認識せずに最初の行を評価するため、複数行のパイプラインをIExにコピーすると構文エラーが発生する可能性があります。
212 |
213 |
214 | *
215 |
216 | パイプライン演算子を一度だけ使うのをやめましょう。
217 | [[link](#avoid-single-pipelines)]
218 |
219 | ```elixir
220 | # 悪い例
221 | some_string |> String.downcase
222 |
223 | # 良い例
224 | String.downcase(some_string)
225 | ```
226 |
227 | *
228 | 関数チェインの最初の値は関数の戻り値ではなく、通常の変数を使ってください。
229 | [[link](#bare-variables)]
230 |
231 | ```elixir
232 | # これは最悪!
233 | # String.strip("nope" |> String.downcase).にパースされます
234 | String.strip "nope" |> String.downcase
235 |
236 | # 悪い例
237 | String.strip(some_string) |> String.downcase |> String.codepoints
238 |
239 | # 良い例
240 | some_string |> String.strip |> String.downcase |> String.codepoints
241 | ```
242 |
243 | *
244 | 行末に余分な空白を入れないこと。
245 | [[link](#trailing-whitespace)]
246 |
247 | *
248 | ファイルの終わりには空行を入れること。
249 | [[link](#newline-eof)]
250 |
251 |
252 | ### 構文
253 |
254 | *
255 | `def` が引数をとる場合は括弧を使うこと。引数がない場合は省略すること。
256 | [[link](#parentheses)]
257 |
258 | ```elixir
259 | # 悪い例
260 | def some_function arg1, arg2 do
261 | # body omitted
262 | end
263 |
264 | def some_function() do
265 | # body omitted
266 | end
267 |
268 | # 良い例
269 | def some_function(arg1, arg2) do
270 | # body omitted
271 | end
272 |
273 | def some_function do
274 | # body omitted
275 | end
276 | ```
277 |
278 | *
279 | 複数行の`if/unless`に `do:`を使ってはいけない。
280 | [[link](#do-with-multi-line-if-unless)]
281 |
282 | ```elixir
283 | # 悪い例
284 | if some_condition, do:
285 | # a line of code
286 | # another line of code
287 | # note no end in this block
288 |
289 | # 良い例
290 | if some_condition do
291 | # some
292 | # lines
293 | # of code
294 | end
295 | ```
296 |
297 | *
298 | 一行の`if/unless` には`do:`を使うこと。
299 | [[link](#do-with-single-line-if-unless)]
300 |
301 | ```elixir
302 | # 良い例
303 | if some_condition, do: # some_stuff
304 | ```
305 |
306 | *
307 | `unless` に `else`を使ってはいけない。
308 | 正常系が最初に来るように書き直してください。
309 | [[link](#unless-with-else)]
310 |
311 | ```elixir
312 | # 悪い例
313 | unless success? do
314 | IO.puts 'failure'
315 | else
316 | IO.puts 'success'
317 | end
318 |
319 | # 良い例
320 | if success? do
321 | IO.puts 'success'
322 | else
323 | IO.puts 'failure'
324 | end
325 | ```
326 |
327 | *
328 | `cond`構文の最後の条件は常に`true`を使うこと。
329 | [[link](#true-as-last-condition)]
330 |
331 | ```elixir
332 | cond do
333 | 1 + 2 == 5 ->
334 | "Nope"
335 | 1 + 3 == 5 ->
336 | "Uh, uh"
337 | true ->
338 | "OK"
339 | end
340 | ```
341 |
342 | *
343 | 関数名と括弧の間にはスペースを入れないこと。
344 | [[link](#function-names-with-parentheses)]
345 |
346 | ```elixir
347 | # 悪い例
348 | f (3 + 2) + 1
349 |
350 | # 良い例
351 | f(3 + 2) + 1
352 | ```
353 |
354 | *
355 | 関数呼び出しには括弧を使うこと。特にパイプライン演算子の中では必ず使うこと。
356 | [[link](#function-calls-and-parentheses)]
357 |
358 | ```elixir
359 | # 悪い例
360 | f 3
361 |
362 | # 良い例
363 | f(3)
364 |
365 | # 悪い例. rem(2, (3 |> g)) にパースされてしまう
366 | 2 |> rem 3 |> g
367 |
368 | # 良い例
369 | 2 |> rem(3) |> g
370 | ```
371 |
372 | *
373 | `do`ブロックをとるマクロの呼び出しでは括弧を省略すること。
374 | [[link](#macro-calls-and-parentheses)]
375 |
376 | ```elixir
377 | # 悪い例
378 | quote(do
379 | foo
380 | end)
381 |
382 | # 良い例
383 | quote do
384 | foo
385 | end
386 | ```
387 |
388 | *
389 | 引数の最後が関数の場合は括弧を省略してもよい。
390 | [[link](#parentheses-and-function-expressions)]
391 |
392 | ```elixir
393 | # 良い例
394 | Enum.reduce(1..10, 0, fn x, acc ->
395 | x + acc
396 | end)
397 |
398 | # これも良い例
399 | Enum.reduce 1..10, 0, fn x, acc ->
400 | x + acc
401 | end
402 | ```
403 |
404 | *
405 | 変数と区別するため引数がない関数呼び出しでも括弧を使うこと。
406 | (Elixir 1.4からは、このようなあいまいな記述があった場合には警告を出すようになりました)
407 | [[link](#parentheses-and-functions-with-zero-arity)]
408 |
409 | ```elixir
410 | defp do_stuff, do: ...
411 |
412 | # 悪い例
413 | def my_func do
414 | do_stuff # 関数呼び出しなのか変数なのかわからない
415 | end
416 |
417 | # 良い例
418 | def my_func do
419 | do_stuff() # 間違いなく関数呼び出し
420 | end
421 | ```
422 |
423 | *
424 | 連続した`with`節はインデントを揃え、引数の`do:`を新しい行に入れてください。
425 | [[link](#with-clauses)]
426 |
427 | ```elixir
428 | with {:ok, foo} <- fetch(opts, :foo),
429 | {:ok, bar} <- fetch(opts, :bar),
430 | do: {:ok, foo, bar}
431 | ```
432 |
433 | *
434 | `with` に 複数行の`do`ブロックがある場合や、`else`オプションがある場合は複数行の構文を使用してください。
435 | [[link](#with-else)]
436 |
437 | ```elixir
438 | with {:ok, foo} <- fetch(opts, :foo),
439 | {:ok, bar} <- fetch(opts, :bar) do
440 | {:ok, foo, bar}
441 | else
442 | :error ->
443 | {:error, :bad_arg}
444 | end
445 | ```
446 |
447 | ### 命名
448 |
449 | *
450 | アトム、関数、変数には `snake_case` を使うこと。
451 | [[link](#snake-case)]
452 |
453 | ```elixir
454 | # 悪い例
455 | :"some atom"
456 | :SomeAtom
457 | :someAtom
458 |
459 | someVar = 5
460 |
461 | def someFunction do
462 | ...
463 | end
464 |
465 | def SomeFunction do
466 | ...
467 | end
468 |
469 | # 良い例
470 | :some_atom
471 |
472 | some_var = 5
473 |
474 | def some_function do
475 | ...
476 | end
477 | ```
478 |
479 | *
480 | モジュール名は`CamelCase`を使うこと(HTTP, RFC, XMLなどの頭字語はそのままでよい)
481 | [[link](#camel-case)]
482 |
483 | ```elixir
484 | # 悪い例
485 | defmodule Somemodule do
486 | ...
487 | end
488 |
489 | defmodule Some_Module do
490 | ...
491 | end
492 |
493 | defmodule SomeXml do
494 | ...
495 | end
496 |
497 | # 良い例
498 | defmodule SomeModule do
499 | ...
500 | end
501 |
502 | defmodule SomeXML do
503 | ...
504 | end
505 | ```
506 |
507 | *
508 | ガード内で使用できる述語マクロ(コンパイル時にbooleanを返す関数になるもの)には`is_`接頭辞をつけること。
509 | ガード内で使用できる式については [Expressions in Guard Clauses](http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses)を参照してください。
510 | [[link](#predicate-macro-names-with-guards)]
511 |
512 | ```elixir
513 | defmacro is_cool(var) do
514 | quote do: unquote(var) == "cool"
515 | end
516 | ```
517 |
518 | *
519 | ガード内で使わない述語関数は`is_`接頭辞ではなく末尾に`?`をつけること。
520 | [[link](#predicate-macro-names-no-guards)]
521 |
522 | ```elixir
523 | def cool?(var) do
524 | # Complex check if var is cool not possible in a pure function.
525 | end
526 | ```
527 |
528 | *
529 | パブリック関数と同名のプライベート関数を定義したい場合は`do_`を頭につけること。
530 | [[link](#private-functions-with-same-name-as-public)]
531 |
532 | ```elixir
533 | def sum(list), do: do_sum(list, 0)
534 |
535 | # private functions
536 | defp do_sum([], total), do: total
537 | defp do_sum([head|tail], total), do: do_sum(tail, head + total)
538 | ```
539 |
540 |
541 | ### コメント
542 |
543 | *
544 | 表現力豊かなコードを書いてください。 制御フロー、構造、命名を通じてプログラムの意図を伝えてください。
545 | [[link](#self-documenting-code)]
546 |
547 | *
548 | `#` とコメントの間にスペースを一つ入れること。
549 | [[link](#comment-leading-spaces)]
550 |
551 | *
552 | 一語以上のコメントは先頭を大文字にして句読点を使うこと。
553 | ピリオドの後には[スペースを一つ](http://en.wikipedia.org/wiki/Sentence_spacing)入れること。
554 | [[link](#comment-spacing)]
555 |
556 | ```elixir
557 | # 悪い例
558 | String.upcase(some_string) # Capitalize string.
559 | ```
560 |
561 | #### 注釈
562 |
563 | *
564 | 注釈は関連するコードのすぐ上に書くこと。
565 | [[link](#annotations)]
566 |
567 | *
568 | 注釈キーワードの後には: とスペースを入れてから本文を書いてください。
569 | [[link](#annotation-keyword)]
570 |
571 | *
572 | もし問題の説明が複数行になる場合は#の後にスペースを2つ入れてください。
573 | [[link](#multiple-line-annotations)]
574 |
575 | *
576 | もし問題が明らかな場合は注釈キーワードだけを該当行の最後に入れてください。
577 | これは強制ではありません。
578 | [[link](#exceptions-to-annotations)]
579 |
580 | *
581 | 未実装や、将来の機能追加のための注釈には`TODO`を使ってください。
582 | [[link](#todo-notes)]
583 |
584 | *
585 | 壊れたコードの注釈には `FIXME` を使ってください。
586 | [[link](#fixme-notes)]
587 |
588 | *
589 | 遅かったり、非効率的なコードの注釈には`OPTIMIZE` を使ってください。
590 | [[link](#optimize-notes)]
591 |
592 | *
593 | コードの書き方に疑問の残る箇所の注釈には`HACK`を使ってください。
594 | [[link](#hack-notes)]
595 |
596 | *
597 | 正しく動くか確認する必要があるコードの注釈には `REVIEW` を使ってください。
598 | 例: `REVIEW: Are we sure this is how the client does X currently?`
599 | [[link](#review-notes)]
600 |
601 | *
602 | もし必要があるようなら独自の注釈キーワードを使ってもかまいませんが、それらはプロジェクトの `README` などに書かれるべきでしょう。
603 | [[link](#custom-keywords)]
604 |
605 |
606 | ### モジュール
607 |
608 | *
609 | モジュールは一つのファイルに一つだけ定義すること。
610 | ただし内部的にのみ使用しているモジュール(テストなど) の場合はこの限りではない。
611 | [[link](#one-module-per-file)]
612 |
613 | *
614 | キャメルケースのモジュール名をアンダースコア化したファイル名にすること。
615 | [[link](#underscored-filenames)]
616 |
617 | ```elixir
618 | # file is called some_module.ex
619 |
620 | defmodule SomeModule do
621 | end
622 | ```
623 |
624 | *
625 | モジュール名のネストはディレクトリ構造を反映させること。
626 | [[link](#module-name-nesting)]
627 |
628 | ```elixir
629 | # file is called parser/core/xml_parser.ex
630 |
631 | defmodule Parser.Core.XMLParser do
632 | end
633 | ```
634 |
635 | *
636 | `defmodule`の後に空行を入れてはいけない。
637 | [[link](#defmodule-spacing)]
638 |
639 | *
640 | モジュールレベルのコードブロックの後には空行を入れること。
641 | [[link](#module-block-spacing)]
642 |
643 | *
644 | モジュール内の定義順は下記のようにする。
645 | [[link](#module-attribute-ordering)]
646 |
647 | 1. `@moduledoc`
648 | 1. `@behaviour`
649 | 1. `use`
650 | 1. `import`
651 | 1. `alias`
652 | 1. `require`
653 | 1. `defstruct`
654 | 1. `@type`
655 | 1. `@module_attribute`
656 |
657 | それぞれのグループの間には空白行を入れ、アルファベット順でソートしてください。
658 | モジュール定義の例を以下に記します。
659 |
660 | ```elixir
661 | defmodule MyModule do
662 | @moduledoc """
663 | An example module
664 | """
665 |
666 | @behaviour MyBehaviour
667 |
668 | use GenServer
669 |
670 | import Something
671 | import SomethingElse
672 |
673 | alias My.Long.Module.Name
674 | alias My.Other.Module.Name
675 |
676 | require Integer
677 |
678 | defstruct name: nil, params: []
679 |
680 | @type params :: [{binary, binary}]
681 |
682 | @module_attribute :foo
683 | @other_attribute 100
684 |
685 | ...
686 | end
687 | ```
688 |
689 | *
690 | モジュールが自身を参照するには`__MODULE__`疑似変数を使用すること。
691 | これならモジュール名が変更されてもコードの変更が要りません。
692 | [[link](#module-pseudo-variable)]
693 |
694 | ```elixir
695 | defmodule SomeProject.SomeModule do
696 | defstruct [:name]
697 |
698 | def name(%__MODULE__{name: name}), do: name
699 | end
700 | ```
701 |
702 | *
703 | もしモジュール自身の参照にもっとわかりやすい名前を使いたければaliasを使うことができます。
704 | [[link](#alias-self-referencing-modules)]
705 |
706 | ```elixir
707 | defmodule SomeProject.SomeModule do
708 | alias __MODULE__, as: SomeModule
709 |
710 | defstruct [:name]
711 |
712 | def name(%SomeModule{name: name}), do: name
713 | end
714 | ```
715 |
716 |
717 | ### ドキュメント
718 | Elixrのドキュメント(`iex`の中で`h`を入力するか、[ExDoc](https://github.com/elixir-lang/ex_doc)で作られたもの) は[モジュールアトリビュート](http://elixir-lang.org/getting-started/module-attributes.html#as-annotations)である `@moduledoc` と `@doc`を使います。
719 |
720 | *
721 | `@moduledoc` は必ず`defmodule`の次の行に書くこと。
722 | [[link](#moduledocs)]
723 |
724 | ```elixir
725 | # 悪い例
726 |
727 | defmodule SomeModule do
728 |
729 | @moduledoc """
730 | About the module
731 | """
732 | ...
733 | end
734 |
735 | defmodule AnotherModule do
736 | use SomeModule
737 | @moduledoc """
738 | About the module
739 | """
740 | ...
741 | end
742 |
743 | # 良い例
744 |
745 | defmodule SomeModule do
746 | @moduledoc """
747 | About the module
748 | """
749 | ...
750 | end
751 | ```
752 |
753 | *
754 | モジュールについてのドキュメントを書かない場合は `@moduledoc false`を使ってください。
755 | [[link](#moduledoc-false)]
756 |
757 | ```elixir
758 | defmodule SomeModule do
759 | @moduledoc false
760 | ...
761 | end
762 | ```
763 |
764 | *
765 | `@moduledoc`の後には空白行を入れてください。
766 | [[link](#moduledoc-spacing)]
767 |
768 | ```elixir
769 | # 悪い例
770 |
771 | defmodule SomeModule do
772 | @moduledoc """
773 | About the module
774 | """
775 | use AnotherModule
776 | end
777 |
778 | # 良い例
779 | defmodule SomeModule do
780 | @moduledoc """
781 | About the module
782 | """
783 |
784 | use AnotherModule
785 | end
786 | ```
787 |
788 | *
789 | ドキュメントのため、複数行コメント内ではmarkdownを使いましょう。
790 | [[link](#heredocs)]
791 |
792 | ```elixir
793 | # 悪い例
794 |
795 | defmodule SomeModule do
796 | @moduledoc "About the module"
797 | end
798 |
799 | defmodule SomeModule do
800 | @moduledoc """
801 | About the module
802 |
803 | Examples:
804 | iex> SomeModule.some_function
805 | :result
806 | """
807 | end
808 |
809 | # 良い例
810 | defmodule SomeModule do
811 | @moduledoc """
812 | About the module
813 |
814 | ## Examples
815 |
816 | iex> SomeModule.some_function
817 | :result
818 | """
819 | end
820 | ```
821 |
822 |
823 | ### Typespecs
824 |
825 | typespecsは、型と仕様を宣言するための表記法です。
826 | ドキュメント、または静的解析ツールDialyzerに使用されます。
827 | カスタムタイプは、モジュール上部に他のタイプと一緒に定義する必要があります。
828 | ([モジュール](#modules)をみてください)
829 |
830 | *
831 | `@typedoc` と `@type` の定義は一緒に書き、それぞれのペア間には空白行を入れてください。
832 | [[link](#typedocs)]
833 |
834 | ```elixir
835 | defmodule SomeModule do
836 | @moduledoc false
837 |
838 | @typedoc "The name"
839 | @type name :: atom
840 |
841 | @typedoc "The result"
842 | @type result :: {:ok, term} | {:error, term}
843 |
844 | ...
845 | end
846 | ```
847 |
848 | *
849 | 直和型の定義が長過ぎる場合は改行して戻り値の型で整列するようにインデントしてください。
850 | [[link](#union-types)]
851 |
852 | ```elixir
853 | # 悪い例 - インデントしていない
854 | @type long_union_type :: some_type | another_type | some_other_type
855 | | a_final_type
856 |
857 | # 良い例
858 | @type long_union_type :: some_type | another_type | some_other_type
859 | | a_final_type
860 |
861 | # これも良い例 - 一行ごとに型一つ
862 | @type long_union_type :: some_type
863 | | another_type
864 | | some_other_type
865 | | a_final_type
866 | ```
867 |
868 | *
869 | モジュール内で定義された構造体などの型定義は `t`としてください。
870 | [[link](#naming-main-types)]
871 |
872 | ```elixir
873 | defstruct name: nil, params: []
874 |
875 | @type t :: %__MODULE__{
876 | name: String.t,
877 | params: Keyword.t
878 | }
879 | ```
880 |
881 | *
882 | 型定義は関数のすぐ上に空白行無しで書いてください。
883 | [[link](#spec-spacing)]
884 |
885 | ```elixir
886 | @spec some_function(term) :: result
887 | def some_function(some_data) do
888 | {:ok, some_data}
889 | end
890 | ```
891 |
892 |
893 | ### 構造体
894 |
895 | *
896 | もし構造体のフィールドのデフォルト値が全てnilならアトムのリストとしてください。
897 | [[link](#nil-struct-field-defaults)]
898 |
899 | ```elixir
900 | # 悪い例
901 | defstruct name: nil, params: nil
902 |
903 | # 良い例
904 | defstruct [:name, :params]
905 | ```
906 |
907 | *
908 | 複数行に渡る構造体の定義の場合は、最初のキーの位置に合わせてインデントしてください。
909 | [[link](#additional-struct-def-lines)]
910 |
911 | ```elixir
912 | defstruct foo: "test", bar: true, baz: false,
913 | qux: false, quux: nil
914 | ```
915 |
916 |
917 | ### 例外
918 |
919 | *
920 | 例外の名前は`Error`で終わること。
921 | [[link](#exception-names)]
922 |
923 | ```elixir
924 | # 悪い例
925 | defmodule BadHTTPCode do
926 | defexception [:message]
927 | end
928 |
929 | defmodule BadHTTPCodeException do
930 | defexception [:message]
931 | end
932 |
933 | # 良い例
934 | defmodule BadHTTPCodeError do
935 | defexception [:message]
936 | end
937 | ```
938 |
939 | *
940 | エラーメッセージは小文字で句読点を省いてください。
941 | [[link](#lowercase-error-messages)]
942 |
943 | ```elixir
944 | # 悪い例
945 | raise ArgumentError, "This is not valid."
946 |
947 | # 良い例
948 | raise ArgumentError, "this is not valid"
949 | ```
950 |
951 |
952 | ### コレクション
953 |
954 | *
955 | キーワードリストに対して常に特別な構文を使うこと。
956 | [[link](#keyword-list-syntax)]
957 |
958 | ```elixir
959 | # 悪い例
960 | some_value = [{:a, "baz"}, {:b, "qux"}]
961 |
962 | # 良い例
963 | some_value = [a: "baz", b: "qux"]
964 | ```
965 |
966 | *
967 | マップのキーがすべてアトムの場合は短く書けるキーバリュー構文を使うこと。
968 | [[link](#map-key-atom)]
969 |
970 | ```elixir
971 | # 悪い例
972 | %{:a => 1, :b => 2, :c => 0}
973 |
974 | # 良い例
975 | %{a: 1, b: 2, c: 3}
976 | ```
977 |
978 | *
979 | マップのキーにアトムではないものがある場合は冗長なキーバリュー構文を使うこと。
980 | [[link](#map-key-arrow)]
981 |
982 | ```elixir
983 | # 悪い例
984 | %{"c" => 0, a: 1, b: 2}
985 |
986 | # 良い例
987 | %{:a => 1, :b => 2, "c" => 0}
988 | ```
989 |
990 | ### 文字列
991 |
992 | *
993 | 文字列のパターンマッチはバイナリではなく、文字列結合演算子を使用してください。
994 | [[link](#strings-matching-with-concatenator)]
995 |
996 | ```elixir
997 | # 悪い例
998 | <<"my"::utf8, _rest>> = "my string"
999 |
1000 | # 良い例
1001 | "my" <> _rest = "my string"
1002 | ```
1003 |
1004 |
1005 | ### 正規表現
1006 |
1007 | _正規表現に関するガイドラインは今のところありません_
1008 |
1009 |
1010 | ### メタプログラミング
1011 |
1012 | *
1013 | 不要なメタプログラミングをしてはいけない。
1014 | [[link](#avoid-metaprogramming)]
1015 |
1016 |
1017 | ### その他のスタイル
1018 |
1019 | あまり一般的ではないスタイルですが役立つ場合があるかもしれません。
1020 |
1021 | #### Cond
1022 |
1023 | *
1024 | アトムは`true`として評価されるので`cond`の最後に入れるすべてにマッチする節として使うことができます。
1025 | `:else` か `:otherwise` を使うと良いでしょう。
1026 | [[link](#atom-conditions)]
1027 |
1028 | ```elixir
1029 | cond do
1030 | 1 + 2 == 5 ->
1031 | "Nope"
1032 | 1 + 3 == 5 ->
1033 | "Uh, uh"
1034 | :else ->
1035 | "OK"
1036 | end
1037 |
1038 | # is the same as
1039 | cond do
1040 | 1 + 2 == 5 ->
1041 | "Nope"
1042 | 1 + 3 == 5 ->
1043 | "Uh, uh"
1044 | true ->
1045 | "OK"
1046 | end
1047 | ```
1048 |
1049 |
1050 | ### スタイルガイド
1051 |
1052 | 他のスタイルガイドについては [Awesome Elixir][Style Guides] を見てください。
1053 |
1054 |
1055 | ### ツール
1056 |
1057 | [Awesome Elixir][Code Analysis] にコードの静的解析とlintのためのツールがあります。
1058 |
1059 | ## コミュニティへの参加方法
1060 |
1061 |
1062 | ### コントリビュート
1063 |
1064 | 私達はここがElixirのベストプラクティスに関する議論の中心になることを願っています。
1065 | 気軽にイシューを書いたりプルリクエストを送ってください。
1066 | [contributing guidelines](CONTRIBUTING.md)と [code of conduct](CODE_OF_CONDUCT.md) を確認してください。
1067 |
1068 |
1069 | ### 広めてください
1070 | コミュニティスタイルガイドは、コミュニティのサポートなしでは無意味です。
1071 | ツイートしたり、スターをつけたり、Elixirプログラマに広めてください。
1072 |
1073 |
1074 | ## コピーライト
1075 |
1076 |
1077 | ### ライセンス
1078 |
1079 | 
1080 | 本翻訳のライセンスは[Creative Commons Attribution 3.0 Unported License][license]です。
1081 |
1082 |
1083 | ### 帰属
1084 |
1085 | このドキュメントの作成にあたり、ガイドの章立てやコード例の一部、そして原案の多くを[Ruby community style guide]から拝借しました。
1086 | それらの多くのことがElixirにも応用でき、また私達が議論するために _一部の_ ドキュメントを引くことが早くにできました。
1087 |
1088 | ここに、このプロジェクトに対して[親切にもコントリビュートして頂いた方々のリスト][Contributors]を記します。
1089 |
1090 |
1091 | [Chinese Traditional]: https://github.com/elixirtw/elixir_style_guide/blob/master/README_zhTW.md
1092 | [Elixir Style Guide]: https://github.com/christopheradams/elixir_style_guide
1093 | [Stargazers]: https://github.com/christopheradams/elixir_style_guide/stargazers
1094 | [Contributors]: https://github.com/christopheradams/elixir_style_guide/graphs/contributors
1095 | [Elixir]: http://elixir-lang.org
1096 | [Hex]: https://hex.pm/packages
1097 | [Japanese]: https://github.com/kenichirow/elixir_style_guide/blob/master/README-jaJP.md
1098 | [Korean]: https://github.com/marocchino/elixir_style_guide/blob/new-korean/README-koKR.md
1099 | [license]: http://creativecommons.org/licenses/by/3.0/deed.en_US
1100 | [Ruby community style guide]: https://github.com/bbatsov/ruby-style-guide
1101 | [Code Analysis]: https://github.com/h4cc/awesome-elixir#code-analysis
1102 | [Style Guides]: https://github.com/h4cc/awesome-elixir#styleguides
1103 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [The Elixir Style Guide][Elixir Style Guide]
2 |
3 | ## Table of Contents
4 |
5 | * __[Prelude](#prelude)__
6 | * __[About](#about)__
7 | * __[Formatting](#formatting)__
8 | * [Whitespace](#whitespace)
9 | * [Indentation](#indentation)
10 | * [Parentheses](#parentheses)
11 | * [Syntax](#syntax)
12 | * __[The Guide](#the-guide)__
13 | * [Expressions](#expressions)
14 | * [Naming](#naming)
15 | * [Comments](#comments)
16 | * [Comment Annotations](#comment-annotations)
17 | * [Modules](#modules)
18 | * [Documentation](#documentation)
19 | * [Typespecs](#typespecs)
20 | * [Structs](#structs)
21 | * [Exceptions](#exceptions)
22 | * [Collections](#collections)
23 | * [Strings](#strings)
24 | * _Regular Expressions_
25 | * [Metaprogramming](#metaprogramming)
26 | * [Testing](#testing)
27 | * __[Resources](#resources)__
28 | * [Alternative Style Guides](#alternative-style-guides)
29 | * [Tools](#tools)
30 | * __[Getting Involved](#getting-involved)__
31 | * [Contributing](#contributing)
32 | * [Spread the Word](#spread-the-word)
33 | * __[Copying](#copying)__
34 | * [License](#license)
35 | * [Attribution](#attribution)
36 |
37 | ## Prelude
38 |
39 | > Liquid architecture. It's like jazz — you improvise, you work together, you
40 | > play off each other, you make something, they make something.
41 | >
42 | > —Frank Gehry
43 |
44 | Style matters.
45 | [Elixir] has plenty of style but like all languages it can be stifled.
46 | Don't stifle the style.
47 |
48 | ## About
49 |
50 | This is community style guide for the [Elixir programming language][Elixir].
51 | Please feel free to make pull requests and suggestions, and be a part of
52 | Elixir's vibrant community.
53 |
54 | If you're looking for other projects to contribute to please see the
55 | [Hex package manager site][Hex].
56 |
57 |
58 | Translations of the guide are available in the following languages:
59 |
60 | * [Chinese Simplified]
61 | * [Chinese Traditional]
62 | * [French]
63 | * [Japanese]
64 | * [Korean]
65 | * [Portuguese]
66 | * [Spanish]
67 |
68 | ## Formatting
69 |
70 | Elixir v1.6 introduced a [Code Formatter] and [Mix format] task.
71 | The formatter should be preferred for all new projects and source code.
72 |
73 | The rules in this section are applied automatically by the code formatter, but
74 | are provided here as examples of the preferred style.
75 |
76 | ### Whitespace
77 |
78 | *
79 | Avoid trailing whitespace.
80 | [[link](#trailing-whitespace)]
81 |
82 | *
83 | End each file with a newline.
84 | [[link](#newline-eof)]
85 |
86 | *
87 | Use Unix-style line endings (\*BSD/Solaris/Linux/OSX users are covered by
88 | default, Windows users have to be extra careful).
89 | [[link](#line-endings)]
90 |
91 | *
92 | If you're using Git you might want to add the following configuration
93 | setting to protect your project from Windows line endings creeping in:
94 | [[link](#autocrlf)]
95 |
96 | ```sh
97 | git config --global core.autocrlf true
98 | ```
99 |
100 | *
101 | Limit lines to 98 characters.
102 | Otherwise, set the `:line_length` option in your `.formatter.exs` file.
103 | [[link](#line-length)]
104 |
105 | *
106 | Use spaces around operators, after commas, colons and semicolons.
107 | Do not put spaces around matched pairs like brackets, parentheses, etc.
108 | Whitespace might be (mostly) irrelevant to the Elixir runtime, but its proper
109 | use is the key to writing easily readable code.
110 | [[link](#spaces)]
111 |
112 | ```elixir
113 | sum = 1 + 2
114 | {a, b} = {2, 3}
115 | [first | rest] = [1, 2, 3]
116 | Enum.map(["one", <<"two">>, "three"], fn num -> IO.puts(num) end)
117 | ```
118 |
119 | *
120 | Do not use spaces after non-word operators that only take one argument; or
121 | around the range operator.
122 | [[link](#no-spaces)]
123 |
124 | ```elixir
125 | 0 - 1 == -1
126 | ^pinned = some_func()
127 | 5 in 1..10
128 | ```
129 |
130 | *
131 | Use blank lines between `def`s to break up a function into logical
132 | paragraphs.
133 | [[link](#def-spacing)]
134 |
135 | ```elixir
136 | def some_function(some_data) do
137 | some_data |> other_function() |> List.first()
138 | end
139 |
140 | def some_function do
141 | result
142 | end
143 |
144 | def some_other_function do
145 | another_result
146 | end
147 |
148 | def a_longer_function do
149 | one
150 | two
151 |
152 | three
153 | four
154 | end
155 | ```
156 |
157 | *
158 | Don't put a blank line after `defmodule`.
159 | [[link](#defmodule-spacing)]
160 |
161 | *
162 | If the function head and `do:` clause are too long to fit on the same line, put
163 | `do:` on a new line, indented one level more than the previous line.
164 | [[link](#long-dos)]
165 |
166 | ```elixir
167 | def some_function([:foo, :bar, :baz] = args),
168 | do: Enum.map(args, fn arg -> arg <> " is on a very long line!" end)
169 | ```
170 |
171 | When the `do:` clause starts on its own line, treat it as a multiline
172 | function by separating it with blank lines.
173 |
174 | ```elixir
175 | # not preferred
176 | def some_function([]), do: :empty
177 | def some_function(_),
178 | do: :very_long_line_here
179 |
180 | # preferred
181 | def some_function([]), do: :empty
182 |
183 | def some_function(_),
184 | do: :very_long_line_here
185 | ```
186 |
187 | *
188 | Add a blank line after a multiline assignment as a
189 | visual cue that the assignment is 'over'.
190 | [[link](#add-blank-line-after-multiline-assignment)]
191 |
192 | ```elixir
193 | # not preferred
194 | some_string =
195 | "Hello"
196 | |> String.downcase()
197 | |> String.trim()
198 | another_string <> some_string
199 |
200 | # preferred
201 | some_string =
202 | "Hello"
203 | |> String.downcase()
204 | |> String.trim()
205 |
206 | another_string <> some_string
207 | ```
208 |
209 | ```elixir
210 | # also not preferred
211 | something =
212 | if x == 2 do
213 | "Hi"
214 | else
215 | "Bye"
216 | end
217 | String.downcase(something)
218 |
219 | # preferred
220 | something =
221 | if x == 2 do
222 | "Hi"
223 | else
224 | "Bye"
225 | end
226 |
227 | String.downcase(something)
228 | ```
229 |
230 | *
231 | If a list, map, or struct spans multiple lines, put each element, as well as
232 | the opening and closing brackets, on its own line.
233 | Indent each element one level, but not the brackets.
234 | [[link](#multiline-enums)]
235 |
236 | ```elixir
237 | # not preferred
238 | [:first_item, :second_item, :next_item,
239 | :final_item]
240 |
241 | # preferred
242 | [
243 | :first_item,
244 | :second_item,
245 | :next_item,
246 | :final_item
247 | ]
248 | ```
249 |
250 | *
251 | When assigning a list, map, or struct, keep the opening bracket on the same
252 | line as the assignment.
253 | [[link](#multiline-list-assign)]
254 |
255 | ```elixir
256 | # not preferred
257 | list =
258 | [
259 | :first_item,
260 | :second_item
261 | ]
262 |
263 | # preferred
264 | list = [
265 | :first_item,
266 | :second_item
267 | ]
268 | ```
269 |
270 | *
271 | When `case` or `cond` clauses span multiple lines, separate each clause with a
272 | blank line.
273 | [[link](#multiline-case-clauses)]
274 |
275 | ```elixir
276 | # not preferred
277 | case arg do
278 | true ->
279 | :ok
280 | false ->
281 | :error
282 | end
283 |
284 | # preferred
285 | case arg do
286 | true ->
287 | :ok
288 |
289 | false ->
290 | :error
291 | end
292 | ```
293 |
294 | *
295 | Place comments above the line they comment on.
296 | [[link](#comments-above-line)]
297 |
298 | ```elixir
299 | String.first(some_string) # not preferred
300 |
301 | # preferred
302 | String.first(some_string)
303 | ```
304 |
305 | *
306 | Use one space between the leading `#` character of the comment and the text of
307 | the comment.
308 | [[link](#comment-leading-spaces)]
309 |
310 | ```elixir
311 | #not preferred
312 | String.first(some_string)
313 |
314 | # preferred
315 | String.first(some_string)
316 | ```
317 |
318 | ### Indentation
319 |
320 | *
321 | Indent and align successive `with` clauses.
322 | Put the `do:` argument on a new line, aligned with the previous clauses.
323 | [[link](#with-clauses)]
324 |
325 | ```elixir
326 | with {:ok, foo} <- fetch(opts, :foo),
327 | {:ok, my_var} <- fetch(opts, :my_var),
328 | do: {:ok, foo, my_var}
329 | ```
330 |
331 | *
332 | If the `with` expression has a `do` block with more than one line, or has an
333 | `else` option, use multiline syntax.
334 | [[link](#with-else)]
335 |
336 | ```elixir
337 | with {:ok, foo} <- fetch(opts, :foo),
338 | {:ok, my_var} <- fetch(opts, :my_var) do
339 | {:ok, foo, my_var}
340 | else
341 | :error ->
342 | {:error, :bad_arg}
343 | end
344 | ```
345 |
346 | ### Parentheses
347 |
348 | *
349 | Use parentheses for one-arity functions when using the pipe operator (`|>`).
350 | [[link](#parentheses-pipe-operator)]
351 |
352 | ```elixir
353 | # not preferred
354 | some_string |> String.downcase |> String.trim
355 |
356 | # preferred
357 | some_string |> String.downcase() |> String.trim()
358 | ```
359 |
360 | *
361 | Never put a space between a function name and the opening parenthesis.
362 | [[link](#function-names-with-parentheses)]
363 |
364 | ```elixir
365 | # not preferred
366 | f (3 + 2)
367 |
368 | # preferred
369 | f(3 + 2)
370 | ```
371 |
372 | *
373 | Use parentheses in function calls, especially inside a pipeline.
374 | [[link](#function-calls-and-parentheses)]
375 |
376 | ```elixir
377 | # not preferred
378 | f 3
379 |
380 | # preferred
381 | f(3)
382 |
383 | # not preferred and parses as rem(2, (3 |> g)), which is not what you want.
384 | 2 |> rem 3 |> g
385 |
386 | # preferred
387 | 2 |> rem(3) |> g
388 | ```
389 |
390 | *
391 | Omit square brackets from keyword lists whenever they are optional.
392 | [[link](#keyword-list-brackets)]
393 |
394 | ```elixir
395 | # not preferred
396 | some_function(foo, bar, [a: "baz", b: "qux"])
397 |
398 | # preferred
399 | some_function(foo, bar, a: "baz", b: "qux")
400 | ```
401 |
402 | ## The Guide
403 |
404 | The rules in this section may not be applied by the code formatter, but they are
405 | generally preferred practice.
406 |
407 | ### Expressions
408 |
409 | *
410 | Run single-line `def`s that match for the same function together, but separate
411 | multiline `def`s with a blank line.
412 | [[link](#single-line-defs)]
413 |
414 | ```elixir
415 | def some_function(nil), do: {:error, "No Value"}
416 | def some_function([]), do: :ok
417 |
418 | def some_function([first | rest]) do
419 | some_function(rest)
420 | end
421 | ```
422 |
423 | *
424 | If you have more than one multiline `def`, do not use single-line `def`s.
425 | [[link](#multiple-function-defs)]
426 |
427 | ```elixir
428 | def some_function(nil) do
429 | {:error, "No Value"}
430 | end
431 |
432 | def some_function([]) do
433 | :ok
434 | end
435 |
436 | def some_function([first | rest]) do
437 | some_function(rest)
438 | end
439 |
440 | def some_function([first | rest], opts) do
441 | some_function(rest, opts)
442 | end
443 | ```
444 |
445 | *
446 | Use the pipe operator to chain functions together.
447 | [[link](#pipe-operator)]
448 |
449 | ```elixir
450 | # not preferred
451 | String.trim(String.downcase(some_string))
452 |
453 | # preferred
454 | some_string |> String.downcase() |> String.trim()
455 |
456 | # Multiline pipelines are not further indented
457 | some_string
458 | |> String.downcase()
459 | |> String.trim()
460 |
461 | # Multiline pipelines on the right side of a pattern match
462 | # should be indented on a new line
463 | sanitized_string =
464 | some_string
465 | |> String.downcase()
466 | |> String.trim()
467 | ```
468 |
469 | While this is the preferred method, take into account that copy-pasting
470 | multiline pipelines into IEx might result in a syntax error, as IEx will
471 | evaluate the first line without realizing that the next line has a pipeline.
472 | To avoid this, you can wrap the pasted code in parentheses.
473 |
474 | *
475 | Avoid using the pipe operator just once.
476 | [[link](#avoid-single-pipelines)]
477 |
478 | ```elixir
479 | # not preferred
480 | some_string |> String.downcase()
481 |
482 | # preferred
483 | String.downcase(some_string)
484 | ```
485 |
486 | *
487 | Use _bare_ variables in the first part of a function chain.
488 | [[link](#bare-variables)]
489 |
490 | ```elixir
491 | # not preferred
492 | String.trim(some_string) |> String.downcase() |> String.codepoints()
493 |
494 | # preferred
495 | some_string |> String.trim() |> String.downcase() |> String.codepoints()
496 | ```
497 |
498 | *
499 | Use parentheses when a `def` has arguments, and omit them when it doesn't.
500 | [[link](#parentheses)]
501 |
502 | ```elixir
503 | # not preferred
504 | def some_function arg1, arg2 do
505 | # body omitted
506 | end
507 |
508 | def some_function() do
509 | # body omitted
510 | end
511 |
512 | # preferred
513 | def some_function(arg1, arg2) do
514 | # body omitted
515 | end
516 |
517 | def some_function do
518 | # body omitted
519 | end
520 | ```
521 |
522 | *
523 | Use `do:` for single line `if/unless` statements.
524 | [[link](#do-with-single-line-if-unless)]
525 |
526 | ```elixir
527 | # preferred
528 | if some_condition, do: # some_stuff
529 | ```
530 |
531 | *
532 | Never use `unless` with `else`.
533 | Rewrite these with the positive case first.
534 | [[link](#unless-with-else)]
535 |
536 | ```elixir
537 | # not preferred
538 | unless success do
539 | IO.puts('failure')
540 | else
541 | IO.puts('success')
542 | end
543 |
544 | # preferred
545 | if success do
546 | IO.puts('success')
547 | else
548 | IO.puts('failure')
549 | end
550 | ```
551 |
552 | *
553 | Use `true` as the last condition of the `cond` special form when you need a
554 | clause that always matches.
555 | [[link](#true-as-last-condition)]
556 |
557 | ```elixir
558 | # not preferred
559 | cond do
560 | 1 + 2 == 5 ->
561 | "Nope"
562 |
563 | 1 + 3 == 5 ->
564 | "Uh, uh"
565 |
566 | :else ->
567 | "OK"
568 | end
569 |
570 | # preferred
571 | cond do
572 | 1 + 2 == 5 ->
573 | "Nope"
574 |
575 | 1 + 3 == 5 ->
576 | "Uh, uh"
577 |
578 | true ->
579 | "OK"
580 | end
581 | ```
582 |
583 | *
584 | Use parentheses for calls to functions with zero arity, so they can be
585 | distinguished from variables.
586 | Starting in Elixir 1.4, the compiler will warn you about
587 | locations where this ambiguity exists.
588 | [[link](#parentheses-and-functions-with-zero-arity)]
589 |
590 | ```elixir
591 | defp do_stuff, do: ...
592 |
593 | # not preferred
594 | def my_func do
595 | # is this a variable or a function call?
596 | do_stuff
597 | end
598 |
599 | # preferred
600 | def my_func do
601 | # this is clearly a function call
602 | do_stuff()
603 | end
604 | ```
605 |
606 | ### Naming
607 |
608 | *
609 | Use `snake_case` for atoms, functions and variables.
610 | [[link](#snake-case)]
611 |
612 | ```elixir
613 | # not preferred
614 | :"some atom"
615 | :SomeAtom
616 | :someAtom
617 |
618 | someVar = 5
619 |
620 | def someFunction do
621 | ...
622 | end
623 |
624 | # preferred
625 | :some_atom
626 |
627 | some_var = 5
628 |
629 | def some_function do
630 | ...
631 | end
632 | ```
633 |
634 | *
635 | Use `CamelCase` for modules (keep acronyms like HTTP, RFC, XML uppercase).
636 | [[link](#camel-case)]
637 |
638 | ```elixir
639 | # not preferred
640 | defmodule Somemodule do
641 | ...
642 | end
643 |
644 | defmodule Some_Module do
645 | ...
646 | end
647 |
648 | defmodule SomeXml do
649 | ...
650 | end
651 |
652 | # preferred
653 | defmodule SomeModule do
654 | ...
655 | end
656 |
657 | defmodule SomeXML do
658 | ...
659 | end
660 | ```
661 |
662 | *
663 | The names of predicate macros (compile-time generated functions that return a
664 | boolean value) _that can be used within guards_ should be prefixed with `is_`.
665 | For a list of allowed expressions, see the [Guard][Guard Expressions] docs.
666 | [[link](#predicate-macro-names-with-guards)]
667 |
668 | ```elixir
669 | defmacro is_cool(var) do
670 | quote do: unquote(var) == "cool"
671 | end
672 | ```
673 |
674 | *
675 | The names of predicate functions _that cannot be used within guards_ should
676 | have a trailing question mark (`?`) rather than the `is_` (or similar) prefix.
677 | [[link](#predicate-macro-names-no-guards)]
678 |
679 | ```elixir
680 | def cool?(var) do
681 | # Complex check if var is cool not possible in a pure function.
682 | end
683 | ```
684 |
685 | *
686 | Private functions with the same name as public functions should start with
687 | `do_`.
688 | [[link](#private-functions-with-same-name-as-public)]
689 |
690 | ```elixir
691 | def sum(list), do: do_sum(list, 0)
692 |
693 | # private functions
694 | defp do_sum([], total), do: total
695 | defp do_sum([head | tail], total), do: do_sum(tail, head + total)
696 | ```
697 |
698 | ### Comments
699 |
700 | *
701 | Write expressive code and try to convey your program's intention through
702 | control-flow, structure and naming.
703 | [[link](#expressive-code)]
704 |
705 | *
706 | Comments longer than a word are capitalized, and sentences use punctuation.
707 | Use [one space][Sentence Spacing] after periods.
708 | [[link](#comment-grammar)]
709 |
710 | ```elixir
711 | # not preferred
712 | # these lowercase comments are missing punctuation
713 |
714 | # preferred
715 | # Capitalization example
716 | # Use punctuation for complete sentences.
717 | ```
718 |
719 | *
720 | Limit comment lines to 100 characters.
721 | [[link](#comment-line-length)]
722 |
723 | #### Comment Annotations
724 |
725 | *
726 | Annotations should usually be written on the line immediately above the
727 | relevant code.
728 | [[link](#annotations)]
729 |
730 | *
731 | The annotation keyword is uppercase, and is followed by a colon and a space,
732 | then a note describing the problem.
733 | [[link](#annotation-keyword)]
734 |
735 | ```elixir
736 | # TODO: Deprecate in v1.5.
737 | def some_function(arg), do: {:ok, arg}
738 | ```
739 |
740 | *
741 | In cases where the problem is so obvious that any documentation would be
742 | redundant, annotations may be left with no note.
743 | This usage should be the exception and not the rule.
744 | [[link](#exceptions-to-annotations)]
745 |
746 | ```elixir
747 | start_task()
748 |
749 | # FIXME
750 | Process.sleep(5000)
751 | ```
752 |
753 | *
754 | Use `TODO` to note missing features or functionality that should be added at a
755 | later date.
756 | [[link](#todo-notes)]
757 |
758 | *
759 | Use `FIXME` to note broken code that needs to be fixed.
760 | [[link](#fixme-notes)]
761 |
762 | *
763 | Use `OPTIMIZE` to note slow or inefficient code that may cause performance
764 | problems.
765 | [[link](#optimize-notes)]
766 |
767 | *
768 | Use `HACK` to note code smells where questionable coding practices were used
769 | and should be refactored away.
770 | [[link](#hack-notes)]
771 |
772 | *
773 | Use `REVIEW` to note anything that should be looked at to confirm it is
774 | working as intended.
775 | For example: `REVIEW: Are we sure this is how the client does X currently?`
776 | [[link](#review-notes)]
777 |
778 | *
779 | Use other custom annotation keywords if it feels appropriate, but be sure to
780 | document them in your project's `README` or similar.
781 | [[link](#custom-keywords)]
782 |
783 | ### Modules
784 |
785 | *
786 | Use one module per file unless the module is only used internally by another
787 | module (such as a test).
788 | [[link](#one-module-per-file)]
789 |
790 | *
791 | Use `snake_case` file names for `CamelCase` module names.
792 | [[link](#underscored-filenames)]
793 |
794 | ```elixir
795 | # file is called some_module.ex
796 |
797 | defmodule SomeModule do
798 | end
799 | ```
800 |
801 | *
802 | Represent each level of nesting within a module name as a directory.
803 | [[link](#module-name-nesting)]
804 |
805 | ```elixir
806 | # file is called parser/core/xml_parser.ex
807 |
808 | defmodule Parser.Core.XMLParser do
809 | end
810 | ```
811 |
812 | *
813 | List module attributes and directives in the following order:
814 | [[link](#module-attribute-ordering)]
815 |
816 | 1. `@moduledoc`
817 | 1. `@behaviour`
818 | 1. `use`
819 | 1. `import`
820 | 1. `alias`
821 | 1. `require`
822 | 1. `@module_attribute`
823 | 1. `defstruct`
824 | 1. `@type`
825 | 1. `@callback`
826 | 1. `@macrocallback`
827 | 1. `@optional_callbacks`
828 |
829 | Add a blank line between each grouping, and sort the terms (like module names)
830 | alphabetically.
831 | Here's an overall example of how you should order things in your modules:
832 |
833 | ```elixir
834 | defmodule MyModule do
835 | @moduledoc """
836 | An example module
837 | """
838 |
839 | @behaviour MyBehaviour
840 |
841 | use GenServer
842 |
843 | import Something
844 | import SomethingElse
845 |
846 | alias My.Long.Module.Name
847 | alias My.Other.Module.Example
848 |
849 | require Integer
850 |
851 | @module_attribute :foo
852 | @other_attribute 100
853 |
854 | defstruct [:name, params: []]
855 |
856 | @type params :: [{binary, binary}]
857 |
858 | @callback some_function(term) :: :ok | {:error, term}
859 |
860 | @macrocallback macro_name(term) :: Macro.t()
861 |
862 | @optional_callbacks macro_name: 1
863 |
864 | ...
865 | end
866 | ```
867 |
868 | *
869 | Use the `__MODULE__` pseudo variable when a module refers to itself. This
870 | avoids having to update any self-references when the module name changes.
871 | [[link](#module-pseudo-variable)]
872 |
873 | ```elixir
874 | defmodule SomeProject.SomeModule do
875 | defstruct [:name]
876 |
877 | def name(%__MODULE__{name: name}), do: name
878 | end
879 | ```
880 |
881 | *
882 | If you want a prettier name for a module self-reference, set up an alias.
883 | [[link](#alias-self-referencing-modules)]
884 |
885 | ```elixir
886 | defmodule SomeProject.SomeModule do
887 | alias __MODULE__, as: SomeModule
888 |
889 | defstruct [:name]
890 |
891 | def name(%SomeModule{name: name}), do: name
892 | end
893 | ```
894 |
895 | *
896 | Avoid repeating fragments in module names and namespaces.
897 | This improves overall readability and
898 | eliminates [ambiguous aliases][Conflicting Aliases].
899 | [[link](#repetitive-module-names)]
900 |
901 | ```elixir
902 | # not preferred
903 | defmodule Todo.Todo do
904 | ...
905 | end
906 |
907 | # preferred
908 | defmodule Todo.Item do
909 | ...
910 | end
911 | ```
912 |
913 | ### Documentation
914 |
915 | Documentation in Elixir (when read either in `iex` with `h` or generated with
916 | [ExDoc]) uses the [Module Attributes] `@moduledoc` and `@doc`.
917 |
918 | *
919 | Always include a `@moduledoc` attribute in the line right after `defmodule` in
920 | your module.
921 | [[link](#moduledocs)]
922 |
923 | ```elixir
924 | # not preferred
925 |
926 | defmodule AnotherModule do
927 | use SomeModule
928 |
929 | @moduledoc """
930 | About the module
931 | """
932 | ...
933 | end
934 |
935 | # preferred
936 |
937 | defmodule AThirdModule do
938 | @moduledoc """
939 | About the module
940 | """
941 |
942 | use SomeModule
943 | ...
944 | end
945 | ```
946 |
947 | *
948 | Use `@moduledoc false` if you do not intend on documenting the module.
949 | [[link](#moduledoc-false)]
950 |
951 | ```elixir
952 | defmodule SomeModule do
953 | @moduledoc false
954 | ...
955 | end
956 | ```
957 |
958 | *
959 | Separate code after the `@moduledoc` with a blank line.
960 | [[link](#moduledoc-spacing)]
961 |
962 | ```elixir
963 | # not preferred
964 | defmodule SomeModule do
965 | @moduledoc """
966 | About the module
967 | """
968 | use AnotherModule
969 | end
970 |
971 | # preferred
972 | defmodule SomeModule do
973 | @moduledoc """
974 | About the module
975 | """
976 |
977 | use AnotherModule
978 | end
979 | ```
980 |
981 | *
982 | Use heredocs with markdown for documentation.
983 | [[link](#heredocs)]
984 |
985 | ```elixir
986 | # not preferred
987 | defmodule SomeModule do
988 | @moduledoc "About the module"
989 | end
990 |
991 | defmodule SomeModule do
992 | @moduledoc """
993 | About the module
994 |
995 | Examples:
996 | iex> SomeModule.some_function
997 | :result
998 | """
999 | end
1000 |
1001 | # preferred
1002 | defmodule SomeModule do
1003 | @moduledoc """
1004 | About the module
1005 |
1006 | ## Examples
1007 |
1008 | iex> SomeModule.some_function
1009 | :result
1010 | """
1011 | end
1012 | ```
1013 |
1014 | ### Typespecs
1015 |
1016 | Typespecs are notation for declaring types and specifications, for
1017 | documentation or for the static analysis tool Dialyzer.
1018 |
1019 | Custom types should be defined at the top of the module with the other
1020 | directives (see [Modules](#modules)).
1021 |
1022 | *
1023 | Place `@typedoc` and `@type` definitions together, and separate each
1024 | pair with a blank line.
1025 | [[link](#typedocs)]
1026 |
1027 | ```elixir
1028 | defmodule SomeModule do
1029 | @moduledoc false
1030 |
1031 | @typedoc "The name"
1032 | @type name :: atom
1033 |
1034 | @typedoc "The result"
1035 | @type result :: {:ok, term} | {:error, term}
1036 |
1037 | ...
1038 | end
1039 | ```
1040 |
1041 | *
1042 | If a union type is too long to fit on a single line, put each part of the
1043 | type on a separate line, indented one level past the name of the type.
1044 | [[link](#union-types)]
1045 |
1046 | ```elixir
1047 | # not preferred
1048 | @type long_union_type ::
1049 | some_type | another_type | some_other_type | one_more_type | a_final_type
1050 |
1051 | # preferred
1052 | @type long_union_type ::
1053 | some_type
1054 | | another_type
1055 | | some_other_type
1056 | | one_more_type
1057 | | a_final_type
1058 | ```
1059 |
1060 | *
1061 | Name the main type for a module `t`, for example: the type specification for a
1062 | struct.
1063 | [[link](#naming-main-types)]
1064 |
1065 | ```elixir
1066 | defstruct [:name, params: []]
1067 |
1068 | @type t :: %__MODULE__{
1069 | name: String.t() | nil,
1070 | params: Keyword.t()
1071 | }
1072 | ```
1073 |
1074 | *
1075 | Place specifications right before the function definition,
1076 | without separating them by a blank line.
1077 | [[link](#spec-spacing)]
1078 |
1079 | ```elixir
1080 | @spec some_function(term) :: result
1081 | def some_function(some_data) do
1082 | {:ok, some_data}
1083 | end
1084 | ```
1085 |
1086 | ### Structs
1087 |
1088 | *
1089 | Use a list of atoms for struct fields that default to `nil`, followed by the
1090 | other keywords.
1091 | [[link](#nil-struct-field-defaults)]
1092 |
1093 | ```elixir
1094 | # not preferred
1095 | defstruct name: nil, params: nil, active: true
1096 |
1097 | # preferred
1098 | defstruct [:name, :params, active: true]
1099 | ```
1100 |
1101 | *
1102 | Omit square brackets when the argument of a `defstruct` is a keyword list.
1103 | [[link](#struct-def-brackets)]
1104 |
1105 | ```elixir
1106 | # not preferred
1107 | defstruct [params: [], active: true]
1108 |
1109 | # preferred
1110 | defstruct params: [], active: true
1111 |
1112 | # required - brackets are not optional, with at least one atom in the list
1113 | defstruct [:name, params: [], active: true]
1114 | ```
1115 |
1116 | *
1117 | If a struct definition spans multiple lines, put each element on its own line,
1118 | keeping the elements aligned.
1119 | [[link](#multiline-structs)]
1120 |
1121 | ```elixir
1122 | defstruct foo: "test",
1123 | bar: true,
1124 | baz: false,
1125 | qux: false,
1126 | quux: 1
1127 | ```
1128 |
1129 | If a multiline struct requires brackets, format it as a multiline list:
1130 |
1131 | ```elixir
1132 | defstruct [
1133 | :name,
1134 | params: [],
1135 | active: true
1136 | ]
1137 | ```
1138 |
1139 | ### Exceptions
1140 |
1141 | *
1142 | Make exception names end with a trailing `Error`.
1143 | [[link](#exception-names)]
1144 |
1145 | ```elixir
1146 | # not preferred
1147 | defmodule BadHTTPCode do
1148 | defexception [:message]
1149 | end
1150 |
1151 | defmodule BadHTTPCodeException do
1152 | defexception [:message]
1153 | end
1154 |
1155 | # preferred
1156 | defmodule BadHTTPCodeError do
1157 | defexception [:message]
1158 | end
1159 | ```
1160 |
1161 | *
1162 | Use lowercase error messages when raising exceptions, with no trailing
1163 | punctuation.
1164 | [[link](#lowercase-error-messages)]
1165 |
1166 | ```elixir
1167 | # not preferred
1168 | raise ArgumentError, "This is not valid."
1169 |
1170 | # preferred
1171 | raise ArgumentError, "this is not valid"
1172 | ```
1173 |
1174 | ### Collections
1175 |
1176 | *
1177 | Always use the special syntax for keyword lists.
1178 | [[link](#keyword-list-syntax)]
1179 |
1180 | ```elixir
1181 | # not preferred
1182 | some_value = [{:a, "baz"}, {:b, "qux"}]
1183 |
1184 | # preferred
1185 | some_value = [a: "baz", b: "qux"]
1186 | ```
1187 |
1188 | *
1189 | Use the shorthand key-value syntax for maps when all of the keys are atoms.
1190 | [[link](#map-key-atom)]
1191 |
1192 | ```elixir
1193 | # not preferred
1194 | %{:a => 1, :b => 2, :c => 0}
1195 |
1196 | # preferred
1197 | %{a: 1, b: 2, c: 3}
1198 | ```
1199 |
1200 | *
1201 | Use the verbose key-value syntax for maps if any key is not an atom.
1202 | [[link](#map-key-arrow)]
1203 |
1204 | ```elixir
1205 | # not preferred
1206 | %{"c" => 0, a: 1, b: 2}
1207 |
1208 | # preferred
1209 | %{:a => 1, :b => 2, "c" => 0}
1210 | ```
1211 |
1212 | ### Strings
1213 |
1214 | *
1215 | Match strings using the string concatenator rather than binary patterns:
1216 | [[link](#strings-matching-with-concatenator)]
1217 |
1218 | ```elixir
1219 | # not preferred
1220 | <<"my"::utf8, _rest::bytes>> = "my string"
1221 |
1222 | # preferred
1223 | "my" <> _rest = "my string"
1224 | ```
1225 |
1226 | ### Regular Expressions
1227 |
1228 | _No guidelines for regular expressions have been added yet._
1229 |
1230 | ### Metaprogramming
1231 |
1232 | *
1233 | Avoid needless metaprogramming.
1234 | [[link](#avoid-metaprogramming)]
1235 |
1236 | ### Testing
1237 |
1238 | *
1239 | When writing [ExUnit] assertions, put the expression being tested to the left
1240 | of the operator, and the expected result to the right, unless the assertion is
1241 | a pattern match.
1242 | [[link](#testing-assert-order)]
1243 |
1244 | ```elixir
1245 | # preferred
1246 | assert actual_function(1) == true
1247 |
1248 | # not preferred
1249 | assert true == actual_function(1)
1250 |
1251 | # required - the assertion is a pattern match
1252 | assert {:ok, expected} = actual_function(3)
1253 | ```
1254 |
1255 | ## Resources
1256 |
1257 | ### Alternative Style Guides
1258 |
1259 | * [Aleksei Magusev's Elixir Style Guide](https://github.com/lexmag/elixir-style-guide#readme)
1260 | — An opinionated Elixir style guide stemming from the coding style practiced
1261 | in the Elixir core libraries.
1262 | Developed by [Aleksei Magusev](https://github.com/lexmag) and
1263 | [Andrea Leopardi](https://github.com/whatyouhide), members of Elixir core team.
1264 | While the Elixir project doesn't adhere to any specific style guide,
1265 | this is the closest available guide to its conventions.
1266 |
1267 | * [Credo's Elixir Style Guide](https://github.com/rrrene/elixir-style-guide#readme)
1268 | — Style Guide for the Elixir language, implemented by
1269 | [Credo](http://credo-ci.org) static code analysis tool.
1270 |
1271 | ### Tools
1272 |
1273 | Refer to [Awesome Elixir][Code Analysis] for libraries and tools that can help
1274 | with code analysis and style linting.
1275 |
1276 | ## Getting Involved
1277 |
1278 | ### Contributing
1279 |
1280 | It's our hope that this will become a central hub for community discussion on
1281 | best practices in Elixir.
1282 | Feel free to open tickets or send pull requests with improvements.
1283 | Thanks in advance for your help!
1284 |
1285 | Check the [contributing guidelines][Contributing] for more information.
1286 |
1287 | ### Spread the Word
1288 |
1289 | A community style guide is meaningless without the community's support. Please
1290 | tweet, [star][Stargazers], and let any Elixir programmer know
1291 | about [this guide][Elixir Style Guide] so they can contribute.
1292 |
1293 | ## Copying
1294 |
1295 | ### License
1296 |
1297 | 
1298 | This work is licensed under a
1299 | [Creative Commons Attribution 3.0 Unported License][License]
1300 |
1301 | ### Attribution
1302 |
1303 | The structure of this guide, bits of example code, and many of the initial
1304 | points made in this document were borrowed from the [Ruby community style guide].
1305 | A lot of things were applicable to Elixir and allowed us to get _some_ document
1306 | out quicker to start the conversation.
1307 |
1308 | Here's the [list of people who have kindly contributed][Contributors] to this
1309 | project.
1310 |
1311 |
1312 | [Chinese Simplified]: https://github.com/geekerzp/elixir_style_guide/blob/master/README-zhCN.md
1313 | [Chinese Traditional]: https://github.com/elixirtw/elixir_style_guide/blob/master/README_zhTW.md
1314 | [Code Analysis]: https://github.com/h4cc/awesome-elixir#code-analysis
1315 | [Code Of Conduct]: https://github.com/elixir-lang/elixir/blob/master/CODE_OF_CONDUCT.md
1316 | [Code Formatter]: https://hexdocs.pm/elixir/Code.html#format_string!/2
1317 | [Conflicting Aliases]: https://elixirforum.com/t/using-aliases-for-fubar-fubar-named-module/1723
1318 | [Contributing]: https://github.com/christopheradams/elixir_style_guide/blob/master/CONTRIBUTING.md
1319 | [Contributors]: https://github.com/christopheradams/elixir_style_guide/graphs/contributors
1320 | [Elixir Style Guide]: https://github.com/christopheradams/elixir_style_guide
1321 | [Elixir]: http://elixir-lang.org
1322 | [ExDoc]: https://github.com/elixir-lang/ex_doc
1323 | [ExUnit]: https://hexdocs.pm/ex_unit/ExUnit.html
1324 | [French]: https://github.com/ronanboiteau/elixir_style_guide/blob/master/README_frFR.md
1325 | [Guard Expressions]: http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses
1326 | [Hex]: https://hex.pm/packages
1327 | [Japanese]: https://github.com/kenichirow/elixir_style_guide/blob/master/README-jaJP.md
1328 | [Korean]: https://github.com/marocchino/elixir_style_guide/blob/new-korean/README-koKR.md
1329 | [License]: http://creativecommons.org/licenses/by/3.0/deed.en_US
1330 | [Mix format]: https://hexdocs.pm/mix/Mix.Tasks.Format.html
1331 | [Module Attributes]: http://elixir-lang.org/getting-started/module-attributes.html#as-annotations
1332 | [Portuguese]: https://github.com/gusaiani/elixir_style_guide/blob/master/README_ptBR.md
1333 | [Ruby community style guide]: https://github.com/bbatsov/ruby-style-guide
1334 | [Sentence Spacing]: http://en.wikipedia.org/wiki/Sentence_spacing
1335 | [Spanish]: https://github.com/albertoalmagro/elixir_style_guide/blob/spanish/README_esES.md
1336 | [Stargazers]: https://github.com/christopheradams/elixir_style_guide/stargazers
1337 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | task :test do
2 | exit_code = 0
3 | files = ["README.md", "CONTRIBUTING.md"]
4 | # 'MD036' # Emphasis used instead of a header
5 | # 'MD033' # Inline HTML - allow for anchor links in each bullet point
6 | rules = ['~MD036', '~MD033'].join(",")
7 | files.each do |file|
8 | begin
9 | sh "mdl --rules #{rules} #{file}"
10 | rescue Exception => ex
11 | exit_code = 1
12 | end
13 | end
14 |
15 | exit exit_code
16 | end
17 |
--------------------------------------------------------------------------------
/mix.exs:
--------------------------------------------------------------------------------
1 | defmodule ElixirStyleGuide.Mixfile do
2 | use Mix.Project
3 |
4 | @project_description """
5 | A community driven style guide for Elixir
6 | """
7 |
8 | @version "0.2.0-dev"
9 | @source_url "https://github.com/christopheradams/elixir_style_guide"
10 |
11 | def project do
12 | [
13 | app: :elixir_style_guide,
14 | version: @version,
15 | elixir: "~> 1.0",
16 | build_embedded: Mix.env() == :prod,
17 | start_permanent: Mix.env() == :prod,
18 | docs: docs(),
19 | description: @project_description,
20 | source_url: @source_url,
21 | package: package(),
22 | deps: deps()
23 | ]
24 | end
25 |
26 | def application do
27 | [applications: [:logger]]
28 | end
29 |
30 | defp deps do
31 | []
32 | end
33 |
34 | defp docs() do
35 | [
36 | source_ref: "v#{@version}",
37 | main: "readme",
38 | extras: [
39 | "README.md": [title: "README"]
40 | ]
41 | ]
42 | end
43 |
44 | defp package do
45 | [
46 | name: :elixir_style_guide,
47 | maintainers: ["Christopher Adams"],
48 | licenses: ["CC-by"],
49 | links: %{
50 | "GitHub" => @source_url
51 | }
52 | ]
53 | end
54 | end
55 |
--------------------------------------------------------------------------------