├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── README.md
├── README_ptBR.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.md:
--------------------------------------------------------------------------------
1 | # [The Elixir Style Guide][Elixir Style Guide]
2 |
3 | ## Table of Contents
4 |
5 | * __[Prelude](#prelude)__
6 | * __[The Guide](#the-guide)__
7 | * [Source Code Layout](#source-code-layout)
8 | * [Syntax](#syntax)
9 | * [Naming](#naming)
10 | * [Comments](#comments)
11 | * [Comment Annotations](#comment-annotations)
12 | * [Modules](#modules)
13 | * [Documentation](#documentation)
14 | * [Typespecs](#typespecs)
15 | * [Structs](#structs)
16 | * [Exceptions](#exceptions)
17 | * _Collections_
18 | * [Strings](#strings)
19 | * _Regular Expressions_
20 | * [Metaprogramming](#metaprogramming)
21 | * [Testing](#testing)
22 | * [Alternative Style Guides](#alternative-style-guides)
23 | * [Tools](#tools)
24 | * __[Getting Involved](#getting-involved)__
25 | * [Contributing](#contributing)
26 | * [Spread the Word](#spread-the-word)
27 | * __[Copying](#copying)__
28 | * [License](#license)
29 | * [Attribution](#attribution)
30 |
31 | ## Prelude
32 |
33 | > Liquid architecture. It's like jazz — you improvise, you work together, you
34 | > play off each other, you make something, they make something.
35 | >
36 | > —Frank Gehry
37 |
38 | Style matters.
39 | [Elixir] has plenty of style but like all languages it can be stifled.
40 | Don't stifle the style.
41 |
42 | ## The Guide
43 |
44 | This is community style guide for the [Elixir programming language][Elixir].
45 | Please feel free to make pull requests and suggestions, and be a part of
46 | Elixir's vibrant community.
47 |
48 | If you're looking for other projects to contribute to please see the
49 | [Hex package manager site][Hex].
50 |
51 |
52 | Translations of the guide are available in the following languages:
53 |
54 | * [Chinese Traditional]
55 | * [Japanese]
56 | * [Korean]
57 | * [Portuguese]
58 | * [Spanish]
59 |
60 | ### Source Code Layout
61 |
62 | *
63 | Use two **spaces** per indentation level.
64 | No hard tabs.
65 | [[link](#spaces-indentation)]
66 |
67 | ```elixir
68 | # not preferred - four spaces
69 | def some_function do
70 | do_something
71 | end
72 |
73 | # preferred
74 | def some_function do
75 | do_something
76 | end
77 | ```
78 |
79 | *
80 | Use Unix-style line endings (\*BSD/Solaris/Linux/OSX users are covered by
81 | default, Windows users have to be extra careful).
82 | [[link](#line-endings)]
83 |
84 | *
85 | If you're using Git you might want to add the following configuration
86 | setting to protect your project from Windows line endings creeping in:
87 | [[link](#autocrlf)]
88 |
89 | ```sh
90 | git config --global core.autocrlf true
91 | ```
92 |
93 | *
94 | Use spaces around operators, after commas, colons and semicolons.
95 | Do not put spaces around matched pairs like brackets, parentheses, etc.
96 | Whitespace might be (mostly) irrelevant to the Elixir runtime, but its proper
97 | use is the key to writing easily readable code.
98 | [[link](#spaces)]
99 |
100 | ```elixir
101 | sum = 1 + 2
102 | {a, b} = {2, 3}
103 | [first | rest] = [1, 2, 3]
104 | Enum.map(["one", <<"two">>, "three"], fn num -> IO.puts num end)
105 | ```
106 |
107 | *
108 | Do not use spaces after non-word operators that only take one argument; or
109 | around the range operator.
110 | [[link](#no-spaces)]
111 |
112 | ```elixir
113 | 0 - 1 == -1
114 | ^pinned = some_func()
115 | 5 in 1..10
116 | ```
117 |
118 | *
119 | Use blank lines between `def`s to break up a function into logical
120 | paragraphs.
121 | [[link](#def-spacing)]
122 |
123 | ```elixir
124 | def some_function(some_data) do
125 | altered_data = Module.function(data)
126 | end
127 |
128 | def some_function do
129 | result
130 | end
131 |
132 | def some_other_function do
133 | another_result
134 | end
135 |
136 | def a_longer_function do
137 | one
138 | two
139 |
140 | three
141 | four
142 | end
143 | ```
144 |
145 | *
146 | ...but run single-line `def`s that match for the same function together.
147 | [[link](#single-line-defs)]
148 |
149 | ```elixir
150 | def some_function(nil), do: {:err, "No Value"}
151 | def some_function([]), do: :ok
152 | def some_function([first | rest]) do
153 | some_function(rest)
154 | end
155 | ```
156 |
157 | *
158 | If you use the `do:` syntax with functions and the line that makes up the
159 | function body is long, put the `do:` on a new line indented one level more
160 | than the previous line.
161 | [[link](#long-dos)]
162 |
163 | ```elixir
164 | def some_function(args),
165 | do: Enum.map(args, fn(arg) -> arg <> " is on a very long line!" end)
166 | ```
167 |
168 | When you use the convention above and you have more than one function clause
169 | using the `do:` syntax, put the `do:` on a new line for each function clause:
170 |
171 | ```elixir
172 | # not preferred
173 | def some_function([]), do: :empty
174 | def some_function(_),
175 | do: :very_long_line_here
176 |
177 | # preferred
178 | def some_function([]),
179 | do: :empty
180 | def some_function(_),
181 | do: :very_long_line_here
182 | ```
183 |
184 | *
185 | If you have more than one multi-line `def`s do not use single-line `def`s.
186 | [[link](#multiple-function-defs)]
187 |
188 | ```elixir
189 | def some_function(nil) do
190 | {:err, "No Value"}
191 | end
192 |
193 | def some_function([]) do
194 | :ok
195 | end
196 |
197 | def some_function([first | rest]) do
198 | some_function(rest)
199 | end
200 |
201 | def some_function([first | rest], opts) do
202 | some_function(rest, opts)
203 | end
204 | ```
205 |
206 | *
207 | Use parentheses for one-arity functions when using the pipe operator (`|>`).
208 | [[link](#parentheses-pipe-operator)]
209 |
210 | ```elixir
211 | # not preferred
212 | some_string |> String.downcase |> String.strip
213 |
214 | # preferred
215 | some_string |> String.downcase() |> String.strip()
216 | ```
217 |
218 | *
219 | Use the pipe operator to chain functions together.
220 | [[link](#pipe-operator)]
221 |
222 | ```elixir
223 | # not preferred
224 | String.strip(String.downcase(some_string))
225 |
226 | # preferred
227 | some_string |> String.downcase() |> String.strip()
228 |
229 | # Multiline pipelines are not further indented
230 | some_string
231 | |> String.downcase()
232 | |> String.strip()
233 |
234 | # Multiline pipelines on the right side of a pattern match
235 | # should be indented on a new line
236 | sanitized_string =
237 | some_string
238 | |> String.downcase()
239 | |> String.strip()
240 | ```
241 |
242 | While this is the preferred method, take into account that copy-pasting
243 | multiline pipelines into IEx might result in a syntax error, as IEx will
244 | evaluate the first line without realizing that the next line has a pipeline.
245 |
246 | *
247 | Avoid using the pipe operator just once.
248 | [[link](#avoid-single-pipelines)]
249 |
250 | ```elixir
251 | # not preferred
252 | some_string |> String.downcase()
253 |
254 | # preferred
255 | String.downcase(some_string)
256 | ```
257 |
258 | *
259 | Use _bare_ variables in the first part of a function chain.
260 | [[link](#bare-variables)]
261 |
262 | ```elixir
263 | # THE WORST!
264 | # This actually parses as String.strip("nope" |> String.downcase()).
265 | String.strip "nope" |> String.downcase()
266 |
267 | # not preferred
268 | String.strip(some_string) |> String.downcase() |> String.codepoints()
269 |
270 | # preferred
271 | some_string |> String.strip() |> String.downcase() |> String.codepoints()
272 | ```
273 |
274 | *
275 | When assigning a list that spans multiple lines, start the list on a newline,
276 | and indent the elements to keep them aligned.
277 | [[link](#multiline-list-assign)]
278 |
279 | ```elixir
280 | # not preferred - no indentation
281 | list = [:first_item, :second_item, :next_item,
282 | :last_item]
283 |
284 | # better, but not preferred - with indentation
285 | list = [:first_item, :second_item, :next_item,
286 | :last_item]
287 |
288 | # preferred - list starts on its own line
289 | # good for shorter, more compact lists
290 | list =
291 | [:first_item, :second_item, :next_item,
292 | :last_item]
293 |
294 | # also preferred - when each element is on its own line
295 | # good for long lists, lists with long elements, or lists with comments
296 | list = [
297 | :first_item,
298 | :second_item,
299 | :next_item,
300 | # comment
301 | :many_items,
302 | :last_item
303 | ]
304 | ```
305 |
306 | *
307 | Avoid trailing whitespace.
308 | [[link](#trailing-whitespace)]
309 |
310 | *
311 | End each file with a newline.
312 | [[link](#newline-eof)]
313 |
314 | ### Syntax
315 |
316 | *
317 | Use parentheses when a `def` has arguments, and omit them when it doesn't.
318 | [[link](#parentheses)]
319 |
320 | ```elixir
321 | # not preferred
322 | def some_function arg1, arg2 do
323 | # body omitted
324 | end
325 |
326 | def some_function() do
327 | # body omitted
328 | end
329 |
330 | # preferred
331 | def some_function(arg1, arg2) do
332 | # body omitted
333 | end
334 |
335 | def some_function do
336 | # body omitted
337 | end
338 | ```
339 |
340 | *
341 | Add a blank line after a multiline assignment as a
342 | visual cue that the assignment is 'over'.
343 | [[link](#add-blank-line-after-multiline-assignment)]
344 |
345 | ```elixir
346 | # not preferred
347 | some_string =
348 | "Hello"
349 | |> String.downcase()
350 | |> String.strip()
351 | another_string <> some_string
352 |
353 | # preferred
354 | some_string =
355 | "Hello"
356 | |> String.downcase()
357 | |> String.strip()
358 |
359 | another_string <> some_string
360 | ```
361 |
362 | ```elixir
363 | # also not preferred
364 | something =
365 | if x == 2 do
366 | "Hi"
367 | else
368 | "Bye"
369 | end
370 | String.downcase(something)
371 |
372 | # preferred
373 | something =
374 | if x == 2 do
375 | "Hi"
376 | else
377 | "Bye"
378 | end
379 |
380 | String.downcase(something)
381 | ```
382 |
383 | *
384 | Never use `do:` for multi-line `if/unless`.
385 | [[link](#do-with-multi-line-if-unless)]
386 |
387 | ```elixir
388 | # not preferred
389 | if some_condition, do:
390 | # a line of code
391 | # another line of code
392 | # note no end in this block
393 |
394 | # preferred
395 | if some_condition do
396 | # some
397 | # lines
398 | # of code
399 | end
400 | ```
401 |
402 | *
403 | Use `do:` for single line `if/unless` statements.
404 | [[link](#do-with-single-line-if-unless)]
405 |
406 | ```elixir
407 | # preferred
408 | if some_condition, do: # some_stuff
409 | ```
410 |
411 | *
412 | Never use `unless` with `else`.
413 | Rewrite these with the positive case first.
414 | [[link](#unless-with-else)]
415 |
416 | ```elixir
417 | # not preferred
418 | unless success? do
419 | IO.puts 'failure'
420 | else
421 | IO.puts 'success'
422 | end
423 |
424 | # preferred
425 | if success? do
426 | IO.puts 'success'
427 | else
428 | IO.puts 'failure'
429 | end
430 | ```
431 |
432 | *
433 | Use `true` as the last condition of the `cond` special form when you need a
434 | clause that always matches.
435 | [[link](#true-as-last-condition)]
436 |
437 | ```elixir
438 | # not preferred
439 | cond do
440 | 1 + 2 == 5 ->
441 | "Nope"
442 | 1 + 3 == 5 ->
443 | "Uh, uh"
444 | :else ->
445 | "OK"
446 | end
447 |
448 | # preferred
449 | cond do
450 | 1 + 2 == 5 ->
451 | "Nope"
452 | 1 + 3 == 5 ->
453 | "Uh, uh"
454 | true ->
455 | "OK"
456 | end
457 | ```
458 |
459 | *
460 | Never put a space between a function name and the opening parenthesis.
461 | [[link](#function-names-with-parentheses)]
462 |
463 | ```elixir
464 | # not preferred
465 | f (3 + 2) + 1
466 |
467 | # preferred
468 | f(3 + 2) + 1
469 | ```
470 |
471 | *
472 | Use parentheses in function calls, especially inside a pipeline.
473 | [[link](#function-calls-and-parentheses)]
474 |
475 | ```elixir
476 | # not preferred
477 | f 3
478 |
479 | # preferred
480 | f(3)
481 |
482 | # not preferred and parses as rem(2, (3 |> g)), which is not what you want.
483 | 2 |> rem 3 |> g
484 |
485 | # preferred
486 | 2 |> rem(3) |> g
487 | ```
488 |
489 | *
490 | Omit parentheses in macro calls when a do block is passed.
491 | [[link](#macro-calls-and-parentheses)]
492 |
493 | ```elixir
494 | # not preferred
495 | quote(do
496 | foo
497 | end)
498 |
499 | # preferred
500 | quote do
501 | foo
502 | end
503 | ```
504 |
505 | *
506 | Optionally omit parentheses in function calls (outside a pipeline) when the
507 | last argument is a function expression.
508 | [[link](#parentheses-and-function-expressions)]
509 |
510 | ```elixir
511 | # preferred
512 | Enum.reduce(1..10, 0, fn x, acc ->
513 | x + acc
514 | end)
515 |
516 | # also preferred
517 | Enum.reduce 1..10, 0, fn x, acc ->
518 | x + acc
519 | end
520 | ```
521 |
522 | *
523 | Use parentheses for calls to functions with zero arity, so they can be
524 | distinguished from variables.
525 | Starting in Elixir 1.4, the compiler will warn you about
526 | locations where this ambiguity exists.
527 | [[link](#parentheses-and-functions-with-zero-arity)]
528 |
529 | ```elixir
530 | defp do_stuff, do: ...
531 |
532 | # not preferred
533 | def my_func do
534 | do_stuff # is this a variable or a function call?
535 | end
536 |
537 | # preferred
538 | def my_func do
539 | do_stuff() # this is clearly a function call
540 | end
541 | ```
542 |
543 | *
544 | Always use the special syntax for keyword lists.
545 | [[link](#keyword-list-syntax)]
546 |
547 | ```elixir
548 | # not preferred
549 | some_value = [{:a, "baz"}, {:b, "qux"}]
550 |
551 | # preferred
552 | some_value = [a: "baz", b: "qux"]
553 | ```
554 |
555 | *
556 | Omit square brackets from keyword lists whenever they are optional.
557 | [[link](#keyword-list-brackets)]
558 |
559 | ```elixir
560 | # not preferred
561 | some_function(foo, bar, [a: "baz", b: "qux"])
562 |
563 | # preferred
564 | some_function(foo, bar, a: "baz", b: "qux")
565 | ```
566 |
567 | *
568 | Indent and align successive `with` clauses.
569 | Put the `do:` argument on a new line, indented normally.
570 | [[link](#with-clauses)]
571 |
572 | ```elixir
573 | with {:ok, foo} <- fetch(opts, :foo),
574 | {:ok, bar} <- fetch(opts, :bar),
575 | do: {:ok, foo, bar}
576 | ```
577 |
578 | *
579 | If the `with` expression has a `do` block with more than one line, or has an
580 | `else` option, use multiline syntax.
581 | [[link](#with-else)]
582 |
583 | ```elixir
584 | with {:ok, foo} <- fetch(opts, :foo),
585 | {:ok, bar} <- fetch(opts, :bar) do
586 | {:ok, foo, bar}
587 | else
588 | :error ->
589 | {:error, :bad_arg}
590 | end
591 | ```
592 |
593 | ### Naming
594 |
595 | *
596 | Use `snake_case` for atoms, functions and variables.
597 | [[link](#snake-case)]
598 |
599 | ```elixir
600 | # not preferred
601 | :"some atom"
602 | :SomeAtom
603 | :someAtom
604 |
605 | someVar = 5
606 |
607 | def someFunction do
608 | ...
609 | end
610 |
611 | def SomeFunction do
612 | ...
613 | end
614 |
615 | # preferred
616 | :some_atom
617 |
618 | some_var = 5
619 |
620 | def some_function do
621 | ...
622 | end
623 | ```
624 |
625 | *
626 | Use `CamelCase` for modules (keep acronyms like HTTP, RFC, XML uppercase).
627 | [[link](#camel-case)]
628 |
629 | ```elixir
630 | # not preferred
631 | defmodule Somemodule do
632 | ...
633 | end
634 |
635 | defmodule Some_Module do
636 | ...
637 | end
638 |
639 | defmodule SomeXml do
640 | ...
641 | end
642 |
643 | # preferred
644 | defmodule SomeModule do
645 | ...
646 | end
647 |
648 | defmodule SomeXML do
649 | ...
650 | end
651 | ```
652 |
653 | *
654 | The names of predicate macros (compile-time generated functions that return a
655 | boolean value) _that can be used within guards_ should be prefixed with `is_`.
656 | For a list of allowed expressions, see the [Guard][Guard Expressions] docs.
657 | [[link](#predicate-macro-names-with-guards)]
658 |
659 | ```elixir
660 | defmacro is_cool(var) do
661 | quote do: unquote(var) == "cool"
662 | end
663 | ```
664 |
665 | *
666 | The names of predicate functions _that cannot be used within guards_ should
667 | have a trailing question mark (`?`) rather than the `is_` (or similar) prefix.
668 | [[link](#predicate-macro-names-no-guards)]
669 |
670 | ```elixir
671 | def cool?(var) do
672 | # Complex check if var is cool not possible in a pure function.
673 | end
674 | ```
675 |
676 | *
677 | Private functions with the same name as public functions should start with
678 | `do_`.
679 | [[link](#private-functions-with-same-name-as-public)]
680 |
681 | ```elixir
682 | def sum(list), do: do_sum(list, 0)
683 |
684 | # private functions
685 | defp do_sum([], total), do: total
686 | defp do_sum([head | tail], total), do: do_sum(tail, head + total)
687 | ```
688 |
689 | ### Comments
690 |
691 | *
692 | Write expressive code and try to convey your program's intention through
693 | control-flow, structure and naming.
694 | [[link](#expressive-code)]
695 |
696 | *
697 | Use one space between the leading `#` character of the comment and the text of
698 | the comment.
699 | [[link](#comment-leading-spaces)]
700 |
701 | ```elixir
702 | String.first(some_string) #not preferred
703 | String.first(some_string) # preferred
704 | ```
705 |
706 | *
707 | Comments longer than a word are capitalized, and sentences use punctuation.
708 | Use [one space][Sentence Spacing] after periods.
709 | [[link](#comment-grammar)]
710 |
711 | ```elixir
712 | # not preferred
713 | # these lowercase comments are missing punctuation
714 |
715 | # preferred
716 | # Capitalization example
717 | # Use punctuation for complete sentences.
718 | ```
719 |
720 | #### Comment Annotations
721 |
722 | *
723 | Annotations should usually be written on the line immediately above the
724 | relevant code.
725 | [[link](#annotations)]
726 |
727 | *
728 | The annotation keyword is uppercase, and is followed by a colon and a space,
729 | then a note describing the problem.
730 | [[link](#annotation-keyword)]
731 |
732 | ```elixir
733 | # TODO: Deprecate in v1.5.
734 | def some_function(arg), do: {:ok, arg}
735 | ```
736 |
737 | *
738 | In cases where the problem is so obvious that any documentation would be
739 | redundant, annotations may be left at the end of the offending line with no
740 | note.
741 | This usage should be the exception and not the rule.
742 | [[link](#exceptions-to-annotations)]
743 |
744 | ```elixir
745 | start_task()
746 | Process.sleep(5000) # FIXME
747 | ```
748 |
749 | *
750 | Use `TODO` to note missing features or functionality that should be added at a
751 | later date.
752 | [[link](#todo-notes)]
753 |
754 | *
755 | Use `FIXME` to note broken code that needs to be fixed.
756 | [[link](#fixme-notes)]
757 |
758 | *
759 | Use `OPTIMIZE` to note slow or inefficient code that may cause performance
760 | problems.
761 | [[link](#optimize-notes)]
762 |
763 | *
764 | Use `HACK` to note code smells where questionable coding practices were used
765 | and should be refactored away.
766 | [[link](#hack-notes)]
767 |
768 | *
769 | Use `REVIEW` to note anything that should be looked at to confirm it is
770 | working as intended.
771 | For example: `REVIEW: Are we sure this is how the client does X currently?`
772 | [[link](#review-notes)]
773 |
774 | *
775 | Use other custom annotation keywords if it feels appropriate, but be sure to
776 | document them in your project's `README` or similar.
777 | [[link](#custom-keywords)]
778 |
779 | ### Modules
780 |
781 | *
782 | Use one module per file unless the module is only used internally by another
783 | module (such as a test).
784 | [[link](#one-module-per-file)]
785 |
786 | *
787 | Use `snake_case` file names for `CamelCase` module names.
788 | [[link](#underscored-filenames)]
789 |
790 | ```elixir
791 | # file is called some_module.ex
792 |
793 | defmodule SomeModule do
794 | end
795 | ```
796 |
797 | *
798 | Represent each level of nesting within a module name as a directory.
799 | [[link](#module-name-nesting)]
800 |
801 | ```elixir
802 | # file is called parser/core/xml_parser.ex
803 |
804 | defmodule Parser.Core.XMLParser do
805 | end
806 | ```
807 |
808 | *
809 | Don't put a blank line after `defmodule`.
810 | [[link](#defmodule-spacing)]
811 |
812 | *
813 | Put a blank line after module-level code blocks.
814 | [[link](#module-block-spacing)]
815 |
816 | *
817 | List module attributes and directives in the following order:
818 | [[link](#module-attribute-ordering)]
819 |
820 | 1. `@moduledoc`
821 | 1. `@behaviour`
822 | 1. `use`
823 | 1. `import`
824 | 1. `alias`
825 | 1. `require`
826 | 1. `defstruct`
827 | 1. `@type`
828 | 1. `@module_attribute`
829 | 1. `@callback`
830 | 1. `@macrocallback`
831 | 1. `@optional_callbacks`
832 |
833 | Add a blank line between each grouping, and sort the terms (like module names)
834 | alphabetically.
835 | Here's an overall example of how you should order things in your modules:
836 |
837 | ```elixir
838 | defmodule MyModule do
839 | @moduledoc """
840 | An example module
841 | """
842 |
843 | @behaviour MyBehaviour
844 |
845 | use GenServer
846 |
847 | import Something
848 | import SomethingElse
849 |
850 | alias My.Long.Module.Name
851 | alias My.Other.Module.Example
852 |
853 | require Integer
854 |
855 | defstruct name: nil, params: []
856 |
857 | @type params :: [{binary, binary}]
858 |
859 | @module_attribute :foo
860 | @other_attribute 100
861 |
862 | @callback some_function(term) :: :ok | {:error, term}
863 |
864 | @macrocallback macro_name(term) :: Macro.t
865 |
866 | @optional_callbacks macro_name: 1
867 |
868 | ...
869 | end
870 | ```
871 |
872 | *
873 | Use the `__MODULE__` pseudo variable when a module refers to itself. This
874 | avoids having to update any self-references when the module name changes.
875 | [[link](#module-pseudo-variable)]
876 |
877 | ```elixir
878 | defmodule SomeProject.SomeModule do
879 | defstruct [:name]
880 |
881 | def name(%__MODULE__{name: name}), do: name
882 | end
883 | ```
884 |
885 | *
886 | If you want a prettier name for a module self-reference, set up an alias.
887 | [[link](#alias-self-referencing-modules)]
888 |
889 | ```elixir
890 | defmodule SomeProject.SomeModule do
891 | alias __MODULE__, as: SomeModule
892 |
893 | defstruct [:name]
894 |
895 | def name(%SomeModule{name: name}), do: name
896 | end
897 | ```
898 |
899 | *
900 | Avoid repeating fragments in module names and namespaces.
901 | This improves overall readability and
902 | eliminates [ambiguous aliases][Conflicting Aliases].
903 | [[link](#repetitive-module-names)]
904 |
905 | ```elixir
906 | # not preferred
907 | defmodule Todo.Todo do
908 | ...
909 | end
910 |
911 | # preferred
912 | defmodule Todo.Item do
913 | ...
914 | end
915 | ```
916 |
917 | ### Documentation
918 |
919 | Documentation in Elixir (when read either in `iex` with `h` or generated with
920 | [ExDoc]) uses the [Module Attributes] `@moduledoc` and `@doc`.
921 |
922 | *
923 | Always include a `@moduledoc` attribute in the line right after `defmodule` in
924 | your module.
925 | [[link](#moduledocs)]
926 |
927 | ```elixir
928 | # not preferred
929 |
930 | defmodule SomeModule do
931 |
932 | @moduledoc """
933 | About the module
934 | """
935 | ...
936 | end
937 |
938 | defmodule AnotherModule do
939 | use SomeModule
940 | @moduledoc """
941 | About the module
942 | """
943 | ...
944 | end
945 |
946 | # preferred
947 |
948 | defmodule SomeModule do
949 | @moduledoc """
950 | About the module
951 | """
952 | ...
953 | end
954 | ```
955 |
956 | *
957 | Use `@moduledoc false` if you do not intend on documenting the module.
958 | [[link](#moduledoc-false)]
959 |
960 | ```elixir
961 | defmodule SomeModule do
962 | @moduledoc false
963 | ...
964 | end
965 | ```
966 |
967 | *
968 | Separate code after the `@moduledoc` with a blank line.
969 | [[link](#moduledoc-spacing)]
970 |
971 | ```elixir
972 | # not preferred
973 |
974 | defmodule SomeModule do
975 | @moduledoc """
976 | About the module
977 | """
978 | use AnotherModule
979 | end
980 |
981 | # preferred
982 | defmodule SomeModule do
983 | @moduledoc """
984 | About the module
985 | """
986 |
987 | use AnotherModule
988 | end
989 | ```
990 |
991 | *
992 | Use heredocs with markdown for documentation.
993 | [[link](#heredocs)]
994 |
995 | ```elixir
996 | # not preferred
997 |
998 | defmodule SomeModule do
999 | @moduledoc "About the module"
1000 | end
1001 |
1002 | defmodule SomeModule do
1003 | @moduledoc """
1004 | About the module
1005 |
1006 | Examples:
1007 | iex> SomeModule.some_function
1008 | :result
1009 | """
1010 | end
1011 |
1012 | # preferred
1013 | defmodule SomeModule do
1014 | @moduledoc """
1015 | About the module
1016 |
1017 | ## Examples
1018 |
1019 | iex> SomeModule.some_function
1020 | :result
1021 | """
1022 | end
1023 | ```
1024 |
1025 | ### Typespecs
1026 |
1027 | Typespecs are notation for declaring types and specifications, for
1028 | documentation or for the static analysis tool Dialyzer.
1029 |
1030 | Custom types should be defined at the top of the module with the other
1031 | directives (see [Modules](#modules)).
1032 |
1033 | *
1034 | Place `@typedoc` and `@type` definitions together, and separate each
1035 | pair with a blank line.
1036 | [[link](#typedocs)]
1037 |
1038 | ```elixir
1039 | defmodule SomeModule do
1040 | @moduledoc false
1041 |
1042 | @typedoc "The name"
1043 | @type name :: atom
1044 |
1045 | @typedoc "The result"
1046 | @type result :: {:ok, term} | {:error, term}
1047 |
1048 | ...
1049 | end
1050 | ```
1051 |
1052 | *
1053 | If a union type is too long to fit on a single line, add a newline
1054 | and indent with spaces to keep the types aligned.
1055 | [[link](#union-types)]
1056 |
1057 | ```elixir
1058 | # not preferred - no indentation
1059 | @type long_union_type :: some_type | another_type | some_other_type |
1060 | a_final_type
1061 |
1062 | # preferred
1063 | @type long_union_type :: some_type | another_type | some_other_type |
1064 | a_final_type
1065 |
1066 | # also preferred - one type per line
1067 | @type long_union_type :: some_type |
1068 | another_type |
1069 | some_other_type |
1070 | a_final_type
1071 | ```
1072 |
1073 | *
1074 | Name the main type for a module `t`, for example: the type specification for a
1075 | struct.
1076 | [[link](#naming-main-types)]
1077 |
1078 | ```elixir
1079 | defstruct name: nil, params: []
1080 |
1081 | @type t :: %__MODULE__{
1082 | name: String.t | nil,
1083 | params: Keyword.t
1084 | }
1085 | ```
1086 |
1087 | *
1088 | Place specifications right before the function definition,
1089 | without separating them by a blank line.
1090 | [[link](#spec-spacing)]
1091 |
1092 | ```elixir
1093 | @spec some_function(term) :: result
1094 | def some_function(some_data) do
1095 | {:ok, some_data}
1096 | end
1097 | ```
1098 |
1099 | ### Structs
1100 |
1101 | *
1102 | Use a list of atoms for struct fields that default to `nil`, followed by the
1103 | other keywords.
1104 | [[link](#nil-struct-field-defaults)]
1105 |
1106 | ```elixir
1107 | # not preferred
1108 | defstruct name: nil, params: nil, active: true
1109 |
1110 | # preferred
1111 | defstruct [:name, :params, active: true]
1112 | ```
1113 |
1114 | *
1115 | Omit square brackets when the argument of a `defstruct` is a keyword list.
1116 | [[link](#struct-def-brackets)]
1117 |
1118 | ```elixir
1119 | # not preferred
1120 | defstruct [params: [], active: true]
1121 |
1122 | # preferred
1123 | defstruct params: [], active: true
1124 |
1125 | # required - brackets are not optional, with at least one atom in the list
1126 | defstruct [:name, params: [], active: true]
1127 | ```
1128 |
1129 | *
1130 | Indent additional lines of the struct definition, keeping the first keys
1131 | aligned.
1132 | [[link](#additional-struct-def-lines)]
1133 |
1134 | ```elixir
1135 | defstruct foo: "test", bar: true, baz: false,
1136 | qux: false, quux: 1
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 | _No guidelines for collections have been added yet._
1177 |
1178 | ### Strings
1179 |
1180 | *
1181 | Match strings using the string concatenator rather than binary patterns:
1182 | [[link](#strings-matching-with-concatenator)]
1183 |
1184 | ```elixir
1185 | # not preferred
1186 | <<"my"::utf8, _rest>> = "my string"
1187 |
1188 | # preferred
1189 | "my" <> _rest = "my string"
1190 | ```
1191 |
1192 | ### Regular Expressions
1193 |
1194 | _No guidelines for regular expressions have been added yet._
1195 |
1196 | ### Metaprogramming
1197 |
1198 | *
1199 | Avoid needless metaprogramming.
1200 | [[link](#avoid-metaprogramming)]
1201 |
1202 | ### Testing
1203 |
1204 | *
1205 | When writing [ExUnit] assertions, be consistent with the order of the expected
1206 | and actual values under testing.
1207 | Prefer placing the expected result on the right, unless the assertion is a
1208 | pattern match.
1209 | [[link](#testing-assert-order)]
1210 |
1211 | ```elixir
1212 | # preferred - expected result on the right
1213 | assert actual_function(1) == true
1214 | assert actual_function(2) == false
1215 |
1216 | # not preferred - inconsistent order
1217 | assert actual_function(1) == true
1218 | assert false == actual_function(2)
1219 |
1220 | # required - the assertion is a pattern match
1221 | assert {:ok, expected} = actual_function(3)
1222 | ```
1223 |
1224 | ### Alternative Style Guides
1225 |
1226 | * [Aleksei Magusev's Elixir Style Guide](https://github.com/lexmag/elixir-style-guide#readme)
1227 | — An opinionated Elixir style guide stemming from the coding style practiced
1228 | in the Elixir core libraries.
1229 | Developed by [Aleksei Magusev](https://github.com/lexmag) and
1230 | [Andrea Leopardi](https://github.com/whatyouhide), members of Elixir core team.
1231 | While the Elixir project doesn't adhere to any specific style guide,
1232 | this is the closest available guide to its conventions.
1233 |
1234 | * [Credo's Elixir Style Guide](https://github.com/rrrene/elixir-style-guide#readme)
1235 | — Style Guide for the Elixir language, implemented by
1236 | [Credo](http://credo-ci.org) static code analysis tool.
1237 |
1238 | ### Tools
1239 |
1240 | Refer to [Awesome Elixir][Code Analysis] for libraries and tools that can help
1241 | with code analysis and style linting.
1242 |
1243 | ## Getting Involved
1244 |
1245 | ### Contributing
1246 |
1247 | It's our hope that this will become a central hub for community discussion on
1248 | best practices in Elixir.
1249 | Feel free to open tickets or send pull requests with improvements.
1250 | Thanks in advance for your help!
1251 |
1252 | Check the [contributing guidelines][Contributing]
1253 | and [code of conduct][Code Of Conduct] for more information.
1254 |
1255 | ### Spread the Word
1256 |
1257 | A community style guide is meaningless without the community's support. Please
1258 | tweet, [star][Stargazers], and let any Elixir programmer know
1259 | about [this guide][Elixir Style Guide] so they can contribute.
1260 |
1261 | ## Copying
1262 |
1263 | ### License
1264 |
1265 | 
1266 | This work is licensed under a
1267 | [Creative Commons Attribution 3.0 Unported License][License]
1268 |
1269 | ### Attribution
1270 |
1271 | The structure of this guide, bits of example code, and many of the initial
1272 | points made in this document were borrowed from the [Ruby community style guide].
1273 | A lot of things were applicable to Elixir and allowed us to get _some_ document
1274 | out quicker to start the conversation.
1275 |
1276 | Here's the [list of people who have kindly contributed][Contributors] to this
1277 | project.
1278 |
1279 |
1280 | [Chinese Traditional]: https://github.com/elixirtw/elixir_style_guide/blob/master/README_zhTW.md
1281 | [Code Analysis]: https://github.com/h4cc/awesome-elixir#code-analysis
1282 | [Code Of Conduct]: https://github.com/christopheradams/elixir_style_guide/blob/master/CODE_OF_CONDUCT.md
1283 | [Conflicting Aliases]: https://elixirforum.com/t/using-aliases-for-fubar-fubar-named-module/1723
1284 | [Contributing]: https://github.com/elixir-lang/elixir/blob/master/CODE_OF_CONDUCT.md
1285 | [Contributors]: https://github.com/christopheradams/elixir_style_guide/graphs/contributors
1286 | [Elixir Style Guide]: https://github.com/christopheradams/elixir_style_guide
1287 | [Elixir]: http://elixir-lang.org
1288 | [ExDoc]: https://github.com/elixir-lang/ex_doc
1289 | [ExUnit]: https://hexdocs.pm/ex_unit/ExUnit.html
1290 | [Guard Expressions]: http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses
1291 | [Hex]: https://hex.pm/packages
1292 | [Japanese]: https://github.com/kenichirow/elixir_style_guide/blob/master/README-jaJP.md
1293 | [Korean]: https://github.com/marocchino/elixir_style_guide/blob/new-korean/README-koKR.md
1294 | [License]: http://creativecommons.org/licenses/by/3.0/deed.en_US
1295 | [Module Attributes]: http://elixir-lang.org/getting-started/module-attributes.html#as-annotations
1296 | [Portuguese]: https://github.com/gusaiani/elixir_style_guide/blob/master/README_ptBR.md
1297 | [Ruby community style guide]: https://github.com/bbatsov/ruby-style-guide
1298 | [Sentence Spacing]: http://en.wikipedia.org/wiki/Sentence_spacing
1299 | [Spanish]: https://github.com/albertoalmagro/elixir_style_guide/blob/spanish/README_esES.md
1300 | [Stargazers]: https://github.com/christopheradams/elixir_style_guide/stargazers
1301 |
1302 |
--------------------------------------------------------------------------------
/README_ptBR.md:
--------------------------------------------------------------------------------
1 | # [O Guia de Estilo Elixir][Guia de Estilo Elixir]
2 |
3 | ## Índice
4 |
5 | * __[Introdução](#introducao)__
6 | * __[O Guia de Estilo Elixir](#o-guia)__
7 | * [Layout do Código](#layout-codigo)
8 | * [Sintaxe](#sintaxe)
9 | * [Nomenclatura](#nomenclatura)
10 | * [Comentários](#comentarios)
11 | * [Anotações em Comentários](#anotacoes-comentarios)
12 | * [Módulos](#modulos)
13 | * [Documentação](#documentacao)
14 | * [Typespecs](#typespecs)
15 | * [Structs](#structs)
16 | * [Exceções](#excecoes)
17 | * _Coleções_
18 | * [Strings](#strings)
19 | * _Expressões Regulares_
20 | * [Metaprogramação](#metaprogramming)
21 | * [Testes](#testes)
22 | * [Guias de Estilo Alternativos](#guias-estilo-alternativos)
23 | * [Ferramentas](#ferramentas)
24 | * __[Participando](#participando)__
25 | * [Contribuindo](#contribuindo)
26 | * [Espalhe](#espalhe)
27 | * __[Cópias](#copias)__
28 | * [Licença](#licenca)
29 | * [Atribuição](#atribuicao)
30 |
31 | ## Introdução
32 |
33 | > Arquitetura líquida. É como o jazz - você improvisa, você trabalha junto,
34 | > você se inspira nos outros, você cria alguma coisa, eles criam alguma coisa.
35 | >
36 | > —Frank Gehry
37 |
38 | Estilo é importante.
39 | [Elixir] tem muito estilo, mas como todas as linguagens, ele pode ser estragado.
40 | Não estrague o estilo.
41 |
42 | ## O Guia
43 |
44 | Este é o guia de estilo da comunidade para a [Linguagem de Programação Elixir][Elixir].
45 | Sinta-se à vontade para enviar pull requests e sugestões, e seja parte da
46 | vibrante comunidade do Elixir.
47 |
48 | Se você está procurando outros projetos para contribuir, por gentileza confira o [site do gerenciador de pacotes Hex][Hex].
49 |
50 |
51 | Traduções deste guia estão disponíveis nas seguintes línguas:
52 |
53 | * [Chinês Tradicional]
54 | * [Coreano]
55 | * [Espanhol]
56 | * [Inglês]
57 | * [Japonês]
58 | * [Português]
59 |
60 | ### Layout do Código Fonte
61 |
62 | *
63 | Use dois **espaços** por nível de recuo.
64 | Não use hard tabs.
65 | [[link](#indentacao-com-espacos)]
66 |
67 | ```elixir
68 | # não recomendado - quatro espaços
69 | def alguma_funcao do
70 | fazer_algo
71 | end
72 |
73 | # recomendado
74 | def alguma_funcao do
75 | fazer_algo
76 | end
77 | ```
78 |
79 | *
80 | Use quebra de linha estilo Unix (\*Usuários de BSD/Solaris/Linux/OSX por padrão
81 | estão cobertos, usuários Windows tem que tomar muito cuidado).
82 | [[link](#quebra-de-linha)]
83 |
84 | *
85 | Se você está usando Git talvez você queira adicionar a seguinte
86 | configuração para evitar quebras de linha Windows adicionadas acidentalmente:
87 | [[link](#autocrlf)]
88 |
89 | ```sh
90 | git config --global core.autocrlf true
91 | ```
92 |
93 | *
94 | Use espaço ao redor de operadores, depois de vírgulas, dois pontos e ponto e vírgulas.
95 | Não coloque espaço ao redor de pares correspondentes como parênteses, colchetes e chaves.
96 | Espaço pode ser (na maioria das vezes) irrelevante no runtime do Elixir, mas
97 | seu uso apropriado é essencial para se escrever código leǵivel.
98 | [[link](#espacos)]
99 |
100 | ```elixir
101 | soma = 1 + 2
102 | {a, b} = {2, 3}
103 | [primeiro | resto] = [1, 2, 3]
104 | Enum.map(["um", <<"dois">>, "três"], fn num -> IO.puts num end)
105 | ```
106 |
107 | *
108 | Não use espaço depois de operadores que não são palavras e recebem um argumento;
109 | ou ao redor do operador range.
110 | [[link](#sem-espacos)]
111 |
112 | ```elixir
113 | 0 - 1 == -1
114 | ^pinned = alguma_funcao()
115 | 5 in 1..10
116 | ```
117 |
118 | *
119 | Use linhas em branco entre `def`s para quebrar uma função em seus parágrafos
120 | lógicos.
121 | [[link](#espacamento-def)]
122 |
123 | ```elixir
124 | def alguma_funcao(algum_dado) do
125 | dado_alterado = Module.function(algum_dado)
126 | end
127 |
128 | def alguma_funcao do
129 | resultado
130 | end
131 |
132 | def alguma_outra_funcao do
133 | outro_resultado
134 | end
135 |
136 | def uma_funcao_mais_longa do
137 | um
138 | dois
139 |
140 | três
141 | quatro
142 | end
143 | ```
144 |
145 | *
146 | ...mas coloque junto `def`s de uma linha só que correspondam à mesma função.
147 | [[link](#defs-de-uma-linha)]
148 |
149 | ```elixir
150 | def alguma_funcao(nil), do: {:err, "Nenhum Valor"}
151 | def alguma_funcao([]), do: :ok
152 | def alguma_funcao([primeiro | resto]) do
153 | alguma_funcao(resto)
154 | end
155 | ```
156 |
157 | *
158 | Se você usar a sintaxe `do:` em funções, e o corpo da função tiver uma linha longa, coloque o `do:` em uma nova linha com um nível de indentação a mais do que a linha anterior.
159 | [[link](#dos-longos)]
160 |
161 | ```elixir
162 | def alguma_funcao(args),
163 | do: Enum.map(args, fn(arg) -> arg <> " está em uma linha muito longa!" end)
164 | ```
165 |
166 | Quando você usar a convenção acima e tiver mais que uma cláusula
167 | usando a sintaxe `do:`, coloque o `do:` em uma nova linha para cada cláusula:
168 |
169 | ```elixir
170 | # não recomendado
171 | def alguma_funcao([]), do: :vazio
172 | def alguma_funcao(_),
173 | do: :linha_muito_longa_aqui
174 |
175 | # recomendado
176 | def alguma_funcao([]),
177 | do: :vazio
178 | def alguma_funcao(_),
179 | do: :linha_muito_longa_aqui
180 | ```
181 |
182 | *
183 | Se você tiver mais que um `def` multilinha, não use `def`s de uma linha.
184 | [[link](#multiplos-defs-funcao)]
185 |
186 | ```elixir
187 | def alguma_funcao(nil) do
188 | {:err, "Nenhum Valor"}
189 | end
190 |
191 | def alguma_funcao([]) do
192 | :ok
193 | end
194 |
195 | def alguma_funcao([primeiro | resto]) do
196 | alguma_funcao(resto)
197 | end
198 |
199 | def alguma_funcao([primeiro | resto], opts) do
200 | alguma_funcao(resto, opts)
201 | end
202 | ```
203 |
204 | *
205 | Use parênteses em funções de aridade um ao usar o operador
206 | pipe (`|>`)
207 | [[link](#operador-pipe-parenteses)]
208 |
209 | ```elixir
210 | # não recomendado
211 | alguma_string |> String.downcase |> String.strip
212 |
213 | # recomendado
214 | alguma_string |> String.downcase() |> String.strip()
215 | ```
216 |
217 | *
218 | Use o operador pipe (`|>`) para encadear funções.
219 | [[link](#operador-pipe)]
220 |
221 | ```elixir
222 | # não recomendado
223 | String.strip(String.downcase(alguma_string))
224 |
225 | # recomendado
226 | alguma_string |> String.downcase |> String.strip
227 |
228 | # Pipelines multilinha não recebem indentação extra
229 | alguma_string
230 | |> String.downcase
231 | |> String.strip
232 |
233 | # Pipelines multilinha do lado direito de um pattern match
234 | # devem ser indentados em uma nova linha
235 | string_sanitizada =
236 | alguma_string
237 | |> String.downcase
238 | |> String.strip
239 | ```
240 |
241 | Mesmo este sendo o método recomendado, lembre-se que copiar e colar
242 | pipelines multilinha no IEx pode resultar em erro de sintaxe, já que o
243 | IEx vai avaliar a primeira linha sem perceber que a próxima linha tem um pipeline.
244 |
245 | *
246 | Evite usar o operador pipe uma vez só.
247 | [[link](#evite-pipelines-solitarios)]
248 |
249 | ```elixir
250 | # não recomendado
251 | alguma_string |> String.downcase
252 |
253 | # recomendado
254 | String.downcase(alguma_string)
255 | ```
256 |
257 | *
258 | Use variáveis _sozinhas_ na primeira parte de uma cadeia de funções.
259 | [[link](#variaveis-sozinhas)]
260 |
261 | ```elixir
262 | # PIOR JEITO!
263 | # Isto é interpretado como String.strip("não" |> String.downcase).
264 | String.strip "não" |> String.downcase()
265 |
266 | # não recomendado
267 | String.strip(alguma_string) |> String.downcase() |> String.codepoints()
268 |
269 | # recomendado
270 | alguma_string |> String.strip() |> String.downcase() |> String.codepoints()
271 | ```
272 |
273 | *
274 | Ao declarar uma linha que abrange múltiplas linhas, comece a lista em uma nova linha,
275 | e indente os elementos para mantê-los alinhados.
276 | [[link](#declaracao-list-multilinha)]
277 |
278 | ```elixir
279 | # não recomendado - sem indentação
280 | lista = [:primeiro_item, :segundo_item, :proximo_item,
281 | :ultimo_item]
282 |
283 | # melhor, mas não recomendado - com indentação
284 | lista = [:primeiro_item, :segundo_item, :proximo_item,
285 | :ultimo_item]
286 |
287 | # recomendado - lista começa em uma linha própria
288 | # bom para listas menores
289 | lista =
290 | [:primeiro_item, :segundo_item, :proximo_item,
291 | :ultimo_item]
292 |
293 | # também recomendado - com cada elemento em uma linha
294 | # bom para listas longas, listas com elementos longos ou listas com comentários
295 | lista = [
296 | :primeiro_item,
297 | :segundo_item,
298 | :proximo_item,
299 | # comentário
300 | :muitos_itens,
301 | :ultimo_item
302 | ]
303 | ```
304 |
305 | *
306 | Evite espaço em branco no fim das linhas
307 | [[link](#espaco-branco-direita)]
308 |
309 | *
310 | Termine todos os arquivos com uma nova linha.
311 | [[link](#eof-nova-linha)]
312 |
313 | ### Sintaxe
314 |
315 | *
316 | Use parênteses quando um `def` tiver argumentos, e omita os parênteses quando ele não tiver argumentos.
317 | [[link](#parenteses)]
318 |
319 | ```elixir
320 | # não recomendado
321 | def alguma_funcao arg1, arg2 do
322 | # corpo omitido
323 | end
324 |
325 | def alguma_funcao() do
326 | # corpo omitido
327 | end
328 |
329 | # recomendado
330 | def alguma_funcao(arg1, arg2) do
331 | # corpo omitido
332 | end
333 |
334 | def alguma_funcao do
335 | # corpo omitido
336 | end
337 | ```
338 |
339 | *
340 | Adicione uma linha em branco após uma declaração multilinha
341 | sinalizando que a declaração terminou.
342 | [[link](#adicione-linha-em-branco-apos-declaracao-multilinha)]
343 |
344 | ```elixir
345 | # não recomendado
346 | alguma_string =
347 | "Oi"
348 | |> String.downcase
349 | |> String.strip
350 | outra_string <> alguma_string
351 |
352 | # recomendado
353 | alguma_string =
354 | "Oi"
355 | |> String.downcase
356 | |> String.strip
357 |
358 | outra_string <> alguma_string
359 | ```
360 |
361 | ```elixir
362 | # também não recomendado
363 | alguma_coisa =
364 | if x == 2 do
365 | "Oi"
366 | else
367 | "Tchau"
368 | end
369 | String.downcase(alguma_coisa)
370 |
371 | # recomendado
372 | alguma_coisa =
373 | if x == 2 do
374 | "Oi"
375 | else
376 | "Tchau"
377 | end
378 |
379 | String.downcase(alguma_coisa)
380 | ```
381 |
382 | *
383 | Nunca use `do:` para `if` ou `unless` multilinha.
384 | [[link](#do-com-if-unless-multilinha)]
385 |
386 | ```elixir
387 | # não recomendado
388 | if alguma_condicao, do:
389 | # uma linha de código
390 | # outra linha de código
391 | # note que este bloco não tem end
392 |
393 | # recomendado
394 | if alguma_condicao do
395 | # algumas
396 | # linhas
397 | # de código
398 | end
399 | ```
400 |
401 | *
402 | Use `do:` para `if/unless` de uma linha só.
403 | [[link](#do-de-uma-linha-só-if-unless)]
404 |
405 | ```elixir
406 | # recomendado
407 | if alguma_condicao, do: # alguma_coisa
408 | ```
409 |
410 | *
411 | Nunca use `unless` com `else`.
412 | Reescreva estes com apenas casos positivos.
413 | [[link](#unless-com-else)]
414 |
415 | ```elixir
416 | # não recomendado
417 | unless successo? do
418 | IO.puts 'falha'
419 | else
420 | IO.puts 'successo'
421 | end
422 |
423 | # recomendado
424 | if successo? do
425 | IO.puts 'successo'
426 | else
427 | IO.puts 'falha'
428 | end
429 | ```
430 |
431 | *
432 | Use `true` como a última condição do `cond` quando você precisa de uma
433 | cláusula que sempre dê match.
434 | [[link](#true-como-ultima-condicao)]
435 |
436 | ```elixir
437 | # não recomendado
438 | cond do
439 | 1 + 2 == 5 ->
440 | "Não"
441 | 1 + 3 == 5 ->
442 | "Oh, oh"
443 | :else ->
444 | "OK"
445 | end
446 |
447 | # recomendado
448 | cond do
449 | 1 + 2 == 5 ->
450 | "Não"
451 | 1 + 3 == 5 ->
452 | "Oh, oh"
453 | true ->
454 | "OK"
455 | end
456 | ```
457 |
458 | *
459 | Nunca coloque um espaço entre o nome da função e a abertura dos parênteses.
460 | [[link](#nomes-de-funcao-com-parenteses)]
461 |
462 | ```elixir
463 | # não recomendado
464 | f (3 + 2) + 1
465 |
466 | # recomendado
467 | f(3 + 2) + 1
468 | ```
469 |
470 | *
471 | Use parênteses em chamadas de função, especialmente dentro de uma pipeline.
472 | [[link](#chamada-de-funcao-com-parentese)]
473 |
474 | ```elixir
475 | # não recomendado
476 | f 3
477 |
478 | # recomendado
479 | f(3)
480 |
481 | # não recomendado e é convertido como rem(2, (3 |> g)), que não é o que você quer.
482 | 2 |> rem 3 |> g
483 |
484 | # recomendado
485 | 2 |> rem(3) |> g
486 | ```
487 |
488 | *
489 | Omita parênteses em chamadas de macro onde um bloco `do` é passado.
490 | [[link](#chamadas-de-macro-e-parênteses)]
491 |
492 | ```elixir
493 | # não recomendado
494 | quote(do
495 | foo
496 | end)
497 |
498 | # recomendado
499 | quote do
500 | foo
501 | end
502 | ```
503 |
504 | *
505 | Parênteses são opcionais em chamadas de função (fora de pipelines) quando o
506 | último argumento é uma expressão de função.
507 | [[link](#parenteses-e-expressoes-de-funcoes)]
508 |
509 | ```elixir
510 | # recomendado
511 | Enum.reduce(1..10, 0, fn x, acc ->
512 | x + acc
513 | end)
514 |
515 | # também recomendado
516 | Enum.reduce 1..10, 0, fn x, acc ->
517 | x + acc
518 | end
519 | ```
520 |
521 | *
522 | Use parênteses quando chamar funções de aridade zero, para que elas
523 | fiquem distintas de variáveis.
524 | A partir do Elixir 1.4 o compilador vai emitir `warnings` em lugares onde
525 | esta ambiguidade existir.
526 | [[link](#parenteses-e-funcoes-aridade-zero)]
527 |
528 | ```elixir
529 | defp fazer_algo, do: ...
530 |
531 | # não recomendado
532 | def minha_funcao do
533 | fazer_algo # isto é uma variável ou uma chamada de função?
534 | end
535 |
536 | # recomendado
537 | def minha_funcao do
538 | fazer_algo() # isto claramente é uma chamada de função
539 | end
540 | ```
541 |
542 | *
543 | Sempre use a sintaxe simplificada para listas de palavras-chave.
544 | [[link](#sintaxe-listas-palavra-chave)]
545 |
546 | ```elixir
547 | # não recomendado
548 | algum_valor = [{:a, "baz"}, {:b, "qux"}]
549 |
550 | # recomendado
551 | algum_valor = [a: "baz", b: "qux"]
552 | ```
553 |
554 | *
555 | Omita colchetes de listas de palavras-chave sempre que eles forem opcionais.
556 | [[link](#colchetes-listas-palavras-chave)]
557 |
558 | ```elixir
559 | # não recomendado
560 | alguma_funcao(foo, bar, [a: "baz", b: "qux"])
561 |
562 | # recomendado
563 | alguma_funcao(foo, bar, a: "baz", b: "qux")
564 | ```
565 |
566 | *
567 | Indente e alinhe cláusulas `with` sucessivas.
568 | Coloque o argumento `do:` em uma nova linha, indentada normalmente.
569 | [[link](#clausulas-with)]
570 |
571 | ```elixir
572 | with {:ok, foo} <- fetch(opts, :foo),
573 | {:ok, bar} <- fetch(opts, :bar),
574 | do: {:ok, foo, bar}
575 | ```
576 |
577 | *
578 | Se a expressão `with` tiver um bloco `do` com mais de uma linha, ou tem uma
579 | opção `else`, use a sintaxe multilinha.
580 | [[link](#with-else)]
581 |
582 | ```elixir
583 | with {:ok, foo} <- fetch(opts, :foo),
584 | {:ok, bar} <- fetch(opts, :bar) do
585 | {:ok, foo, bar}
586 | else
587 | :error ->
588 | {:error, :bad_arg}
589 | end
590 | ```
591 |
592 | ### Nomenclatura
593 |
594 | *
595 | Use `snake_case` para átomos, funções e variáveis.
596 | [[link](#snake-case)]
597 |
598 | ```elixir
599 | # não recomendado
600 | :"algum átomo"
601 | :AlgumAtomo
602 | :algumAtomo
603 |
604 | algumaVar = 5
605 |
606 | def algumaFuncao do
607 | ...
608 | end
609 |
610 | def AlgumaFuncao do
611 | ...
612 | end
613 |
614 | # recomendado
615 | :algum_atom
616 |
617 | alguma_var = 5
618 |
619 | def alguma_funcao do
620 | ...
621 | end
622 | ```
623 |
624 | *
625 | Use `CamelCase` para módulos (mantenha siglas como HTTP, RFC, XML em maiúsculo).
626 | [[link](#camel-case)]
627 |
628 | ```elixir
629 | # não recomendado
630 | defmodule Algummodulo do
631 | ...
632 | end
633 |
634 | defmodule Algum_Modulo do
635 | ...
636 | end
637 |
638 | defmodule AlgumXml do
639 | ...
640 | end
641 |
642 | # recomendado
643 | defmodule AlgumModulo do
644 | ...
645 | end
646 |
647 | defmodule AlgumXML do
648 | ...
649 | end
650 | ```
651 |
652 | *
653 | Os nomes das macros com predicado (funções geradas na hora da compilação que retornam um
654 | valor booleano) _que podem ser usadas dentro de guards_ devem ser prefixados com `is_`.
655 | Para uma lista de expressões permitidas, veja nos documentos [Guard][Guard Expressions].
656 | [[link](#nome-de-macro-com-predicado-em-guards)]
657 |
658 | ```elixir
659 | defmacro is_cool(var) do
660 | quote do: unquote(var) == "cool"
661 | end
662 | ```
663 |
664 | *
665 | Os nomes de funções com predicados _que não podem ser usadas em guards_ devem
666 | ter um ponto de interrogação à direita (`?`) em vez do prefixo `is_` (ou similar).
667 | [[link](#nome-de-macro-de-predicado-sem-guards)]
668 |
669 | ```elixir
670 | def cool?(var) do
671 | # Verificação complexa se var for cool não é possível em uma função pura.
672 | end
673 | ```
674 |
675 | *
676 | Funções privadas com o mesmo nome de funções públicas devem começar com `do_`.
677 | [[link](#funcoes-privadas-com-mesmo-nome-de-publicas)]
678 |
679 | ```elixir
680 | def soma(list), do: do_soma(list, 0)
681 |
682 | # funções privadas
683 | defp do_soma([], total), do: total
684 | defp do_soma([head | tail], total), do: do_soma(tail, head + total)
685 | ```
686 |
687 | ### Comentários
688 |
689 | *
690 | Escreva código expressivo e busque transmitir a intenção do seu programa
691 | através de fluxo de controle, estrutura e nomenclaturas.
692 | [[link](#codigo-expressivo)]
693 |
694 | *
695 | Use um espaço entre o `#` do comentário e o texto do comentário.
696 | [[link](#comentários-espacos-esquerda)]
697 |
698 | ```elixir
699 | String.first(alguma_string) #não recomendado
700 | String.first(alguma_string) # recomendado
701 | ```
702 |
703 | *
704 | Comentários de mais de uma palavra começam com maiúscula, e frases recebem pontuação.
705 | Use [um espaço][Sentence Spacing] depois dos pontos finais.
706 | [[link](#gramatica-comentario)]
707 |
708 | ```elixir
709 | # não recomendado
710 | # este comentário em minúsculas não tem pontuação
711 |
712 | # recomendado
713 | # Exemplo com maiúscula
714 | # Use pontuação em frases completas.
715 | ```
716 |
717 | #### Anotações em Comentários
718 |
719 | *
720 | Anotações normalmente devem vir na linha imediatamente acima do
721 | respectivo código.
722 | [[link](#anotacoes)]
723 |
724 | *
725 | A palavra-chave de anotação é inteira em maiúsculas, seguida por dois-pontos e espaço,
726 | e então uma descrição do problema.
727 | [[link](#palavra-chave-anotacao)]
728 |
729 | ```elixir
730 | # TODO: Deprecate in v2.0.
731 | def alguma_funcao(arg), do: {:ok, arg}
732 | ```
733 |
734 | *
735 | Nos casos em que o problema é tão óbvio que qualquer documentação seria
736 | redundante, as anotações podem vir no fim da linha em questão sem comentário adicional.
737 | Esta forma deve ser a exceção e não a regra.
738 | [[link](#excecoes-anotacoes)]
739 |
740 | ```elixir
741 | start_task()
742 | Process.sleep(5000) # FIXME
743 | ```
744 |
745 | *
746 | Use `TODO` para anotar funcionalidades que faltam ou funcionalidades que devem
747 | ser acrescentadas no futuro.
748 | [[link](#notas-todo)]
749 |
750 | *
751 | Use `FIXME` para anotar código quebrado que precisa ser corrigido.
752 | [[link](#notas-fixme)]
753 |
754 | *
755 | Use `OPTIMIZE` para anotar código lento ou ineficiente que pode causar
756 | problemas de desempenho.
757 | [[link](#notas-optimize)]
758 |
759 | *
760 | Use `HACK` para anotar lugares onde existem práticas questionáveis e que
761 | deveriam ser refatoradas.
762 | [[link](#notas-hack)]
763 |
764 | *
765 | Use `REVIEW` para anotar qualquer coisa que precise ser revista para confirmar
766 | que está funcionando conforme pretendido.
767 | Exemplo: `REVIEW: Temos certeza que é assim que o cliente faz X hoje em dia?`
768 | [[link](#notas-review)]
769 |
770 | *
771 | Use outras palavras-chave customizadas se apropriado, mas se certifique de
772 | documentá-las no `README` do seu projeto ou algo similar.
773 | [[link](#palavras-chave-customizadas)]
774 |
775 | ### Módulos
776 |
777 | *
778 | Use um módulo por arquivo, a não ser que o módulo seja usado apenas
779 | internamente por outro módulo (um teste, por exemplo).
780 | [[link](#um-modulo-por-arquivo)]
781 |
782 | *
783 | Use nomes de arquivo em `snake_case` e nomes de módulo em`CamelCase`.
784 | [[link](#nomes-de-arquivo-underscore)]
785 |
786 | ```elixir
787 | # arquivo chamado algum_modulo.ex
788 |
789 | defmodule AlgumModulo do
790 | end
791 | ```
792 |
793 | *
794 | Expresse cada nível de aninhamento em um nome de módulo como um diretório.
795 | [[link](#aninhamento-nomes-modulo)]
796 |
797 | ```elixir
798 | # arquivo chamado parser/core/xml_parser.ex
799 |
800 | defmodule Parser.Core.XMLParser do
801 | end
802 | ```
803 |
804 | *
805 | Não use uma linha em branco após um `defmodule`.
806 | [[link](#espacamento-defmodule)]
807 |
808 | *
809 | Use uma linha em branco após blocos de código em módulos.
810 | [[link](#espacamento-blocos-module)]
811 |
812 | *
813 | Liste atributos e diretivas de módulo na seguinte ordem:
814 | [[link](#ordenacao-atributos-modulo)]
815 |
816 | 1. `@moduledoc`
817 | 1. `@behaviour`
818 | 1. `use`
819 | 1. `import`
820 | 1. `alias`
821 | 1. `require`
822 | 1. `defstruct`
823 | 1. `@type`
824 | 1. `@module_attribute`
825 | 1. `@callback`
826 | 1. `@macrocallback`
827 | 1. `@optional_callbacks`
828 |
829 | Adicione uma linha em branco entre cada agrupamento, e ordene os termos
830 | (como nomes de módulos) alfabeticamente.
831 | Abaixo um exemplo geral de como você deve ordenar as coisas em seus módulos:
832 |
833 | ```elixir
834 | defmodule MeuModulo do
835 | @moduledoc """
836 | Exemplo de módulo
837 | """
838 |
839 | @behaviour MeuBehaviour
840 |
841 | use GenServer
842 |
843 | import AlgumaCoisa
844 | import OutraCoisa
845 |
846 | alias Meu.Nome.Comprido.Modulo
847 | alias Meu.Outro.Exemplo.Modulo
848 |
849 | require Integer
850 |
851 | defstruct name: nil, params: []
852 |
853 | @type params :: [{binary, binary}]
854 |
855 | @module_attribute :foo
856 | @other_attribute 100
857 |
858 | @callback alguma_funcao(termo) :: :ok | {:error, termo}
859 |
860 | @macrocallback nome_macro(termo) :: Macro.t
861 |
862 | @optional_callbacks nome_macro: 1
863 |
864 | ...
865 | end
866 | ```
867 |
868 | *
869 | Use a pseudo variável `__MODULE__` quando um módulo se referir a si mesmo.
870 | Isto previne que tenhamos que atualizar auto-referências quando o nome do módulo mudar.
871 | [[link](#pseudo-variavel-modulo)]
872 |
873 | ```elixir
874 | defmodule AlgumProjeto.AlgumModulo do
875 | defstruct [:nome]
876 |
877 | def nome(%__MODULE__{nome: nome}), do: nome
878 | end
879 | ```
880 |
881 | *
882 | Se você quiser um nome mais bonito para uma auto-referência de módulo,
883 | crie um alias.
884 | [[link](#alias-modulos-auto-referentes)]
885 |
886 | ```elixir
887 | defmodule AlgumProjeto.AlgumModulo do
888 | alias __MODULE__, as: AlgumModulo
889 |
890 | defstruct [:nome]
891 |
892 | def nome(%AlgumModulo{nome: nome}), do: nome
893 | end
894 | ```
895 |
896 | *
897 | Evite repetir fragmentos em nomes e namespaces de módulos.
898 | Isto melhora a legibilidade e elimina [aliases ambíguos][Conflicting Aliases].
899 | [[link](#nomes-modulo-repetitivos)]
900 |
901 | ```elixir
902 | # não recomendado
903 | defmodule Todo.Todo do
904 | ...
905 | end
906 |
907 | # recomendado
908 | defmodule Todo.Item do
909 | ...
910 | end
911 | ```
912 |
913 | ### Documentação
914 |
915 | Documentação em Elixir (quando lida seja no `iex` com `h` seja gerada com
916 | [ExDoc]) usa os [Atributos de Módulo] `@moduledoc` e `@doc`.
917 |
918 | *
919 | Inclua sempre um atributo `@moduledoc` na linha imediatamente posterior ao `defmodule`
920 | em seu módulo.
921 | [[link](#moduledocs)]
922 |
923 | ```elixir
924 | # não recomendado
925 |
926 | defmodule AlgumModulo do
927 |
928 | @moduledoc """
929 | Informação sobre o módulo.
930 | """
931 | ...
932 | end
933 |
934 | defmodule OutroModulo do
935 | use AlgumModulo
936 | @moduledoc """
937 | Informação sobre o módulo.
938 | """
939 | ...
940 | end
941 |
942 | # recomendado
943 |
944 | defmodule AlgumModulo do
945 | @moduledoc """
946 | Informação sobre o módulo.
947 | """
948 | ...
949 | end
950 | ```
951 |
952 | *
953 | Use `@moduledoc false` se você não pretende documentar o módulo.
954 | [[link](#moduledoc-false)]
955 |
956 | ```elixir
957 | defmodule AlgumModulo do
958 | @moduledoc false
959 | ...
960 | end
961 | ```
962 |
963 | *
964 | Separe o código que vem depois do `@moduledoc` com uma linha em branco.
965 | [[link](#espacamento-moduledoc)]
966 |
967 | ```elixir
968 | # não recomendado
969 |
970 | defmodule AlgumModulo do
971 | @moduledoc """
972 | Informação sobre o módulo.
973 | """
974 | use OutroModulo
975 | end
976 |
977 | # recomendado
978 | defmodule AlgumModulo do
979 | @moduledoc """
980 | Informação sobre o módulo.
981 | """
982 |
983 | use OutroModulo
984 | end
985 | ```
986 |
987 | *
988 | Use heredocs com markdown na documentação.
989 | [[link](#heredocs)]
990 |
991 | ```elixir
992 | # não recomendado
993 |
994 | defmodule AlgumModulo do
995 | @moduledoc "Informação sobre o módulo."
996 | end
997 |
998 | defmodule AlgumModulo do
999 | @moduledoc """
1000 | Informação sobre o módulo.
1001 |
1002 | Exemplos:
1003 | iex> AlgumModulo.alguma_funcao
1004 | :resultado
1005 | """
1006 | end
1007 |
1008 | # recomendado
1009 | defmodule AlgumModulo do
1010 | @moduledoc """
1011 | Informação sobre o módulo.
1012 |
1013 | ## Exemplos
1014 |
1015 | iex> AlgumModulo.alguma_funcao
1016 | :resultado
1017 | """
1018 | end
1019 | ```
1020 |
1021 | ### Typespecs
1022 |
1023 | Typespecs são notações para declarar tipos e especificações,
1024 | para documentação ou para o Dialyzer (ferramenta de
1025 | análise estática).
1026 |
1027 | Tipos customizados devem ser definidos no topo do módulo com as outras
1028 | diretivas (veja [Módulos](#modulos)).
1029 |
1030 | *
1031 | Aplique definições `@typedoc` e `@type` juntas, e separe cada par
1032 | com uma linha em branco.
1033 | [[link](#typedocs)]
1034 |
1035 | ```elixir
1036 | defmodule AlgumModulo do
1037 | @moduledoc false
1038 |
1039 | @typedoc "O nome"
1040 | @type name :: atom
1041 |
1042 | @typedoc "O resultado"
1043 | @type result :: {:ok, termo} | {:error, termo}
1044 |
1045 | ...
1046 | end
1047 | ```
1048 |
1049 | *
1050 | Se um tipo de união for longo demais para caber em um só linha, adicione
1051 | uma nova linha e indente com espaços para alinhar os tipos.
1052 | [[link](#tipos-uniao)]
1053 |
1054 | ```elixir
1055 | # não recomendado - sem indentação
1056 | @type tipo_de_uniao_longo :: algum_tipo | outro_tipo | algum_outro_tipo |
1057 | um_ultimo_tipo
1058 |
1059 | # recomendado
1060 | @type tipo_de_uniao_longo :: algum_tipo | outro_tipo | algum_outro_tipo |
1061 | um_ultimo_tipo
1062 |
1063 | # também recomendado - um tipo por linha
1064 | @type tipo_de_uniao_longo :: algum_tipo |
1065 | outro_tipo |
1066 | algum_outro_tipo |
1067 | um_ultimo_tipo
1068 | ```
1069 |
1070 | *
1071 | Nomeie como `t` o tipo principal de um módulo, por exemplo: a especificação
1072 | de tipo para um struct.
1073 | [[link](#nomeando-tipos-principais)]
1074 |
1075 | ```elixir
1076 | defstruct nome: nil, params: []
1077 |
1078 | @type t :: %__MODULE__{
1079 | nome: String.t | nil,
1080 | params: Keyword.t
1081 | }
1082 | ```
1083 |
1084 | *
1085 | Escreva especificações logo acima da definicação de uma função, sem separá-los
1086 | com linha em branco.
1087 | [[link](#espacamento-specs)]
1088 |
1089 | ```elixir
1090 | @spec alguma_funcao(termo) :: result
1091 | def alguma_funcao(algum_dado) do
1092 | {:ok, algum_dado}
1093 | end
1094 | ```
1095 |
1096 | ### Structs
1097 |
1098 | *
1099 | Use uma lista de átomos para campos de struct que tenham default de `nil`,
1100 | seguidos por outras palavras-chave.
1101 | [[link](#defaults-campos-struct-nil)]
1102 |
1103 | ```elixir
1104 | # não recomendado
1105 | defstruct nome: nil, params: nil, ativo: true
1106 |
1107 | # recomendado
1108 | defstruct [:nome, :params, ativo: true]
1109 | ```
1110 |
1111 | *
1112 | Omita colchetes quando o argumento de um `defstruct` for uma lista
1113 | de palavras-chave.
1114 | [[link](#colchetes-defstruct)]
1115 |
1116 | ```elixir
1117 | # não recomendado
1118 | defstruct [params: [], ativo: true]
1119 |
1120 | # recomendado
1121 | defstruct params: [], ativo: true
1122 |
1123 | # obrigatório - colchetes não são opcionais, com ao menos um átomo na lista
1124 | defstruct [:nome, params: [], ativo: true]
1125 | ```
1126 |
1127 | *
1128 | Indente linhas adicionais de defstruct, mantendo as primeiras chaves alinhadas.
1129 | aligned.
1130 | [[link](#linhas-defstruct-adicionais)]
1131 |
1132 | ```elixir
1133 | defstruct foo: "teste", bar: true, baz: false,
1134 | qux: false, quux: 1
1135 | ```
1136 |
1137 | ### Exceções
1138 |
1139 | *
1140 | Adicione o sufixo `Error` aos nomes de exceções.
1141 | [[link](#nomes-excecoes)]
1142 |
1143 | ```elixir
1144 | # não recomendado
1145 | defmodule BadHTTPCode do
1146 | defexception [:mensagem]
1147 | end
1148 |
1149 | defmodule BadHTTPCodeException do
1150 | defexception [:mensagem]
1151 | end
1152 |
1153 | # recomendado
1154 | defmodule BadHTTPCodeError do
1155 | defexception [:mensagem]
1156 | end
1157 | ```
1158 |
1159 | *
1160 | Use minúsculas em mensagens de erro quando emitindo exceções, sem pontuação
1161 | ao final.
1162 | [[link](#mensagens-erro-minusculas)]
1163 |
1164 | ```elixir
1165 | # não recomendado
1166 | raise ArgumentError, "Isto não é válido."
1167 |
1168 | # recomendado
1169 | raise ArgumentError, "isto é válido"
1170 | ```
1171 |
1172 | ### Coleções
1173 |
1174 | A secão de Coleções do guia ainda não foi adicionada.
1175 |
1176 | ### Strings
1177 |
1178 | *
1179 | Dê match em strings usando o concatenador de strings, e não
1180 | padrões binários.
1181 | [[link](#match-strings-com-concatenador)]
1182 |
1183 | ```elixir
1184 | # não recomendado
1185 | <<"minha"::utf8, _resto>> = "minha string"
1186 |
1187 | # recomendado
1188 | "minha" <> _resto = "minha string"
1189 | ```
1190 |
1191 | ### Expressões Regulares
1192 |
1193 | _A secão de Coleções do guia ainda não foi adicionada._
1194 |
1195 | ### Metaprogramação
1196 |
1197 | *
1198 | Evite metaprogramação desnecessária.
1199 | [[link](#evite-metaprogramacao)]
1200 |
1201 | ### Testes
1202 |
1203 | *
1204 | Ao escrever asserções [ExUnit], mantenha a consistência entre a ordem dos
1205 | valores esperados e reais que estão sob teste.
1206 | Prefira usar o resultado esperado à direita, a não ser que a asserção
1207 | seja um pattern match.
1208 | [[link](#testando-ordem-assert)]
1209 |
1210 | ```elixir
1211 | # recomendado - resultado esperado à direita
1212 | assert minha_funcao(1) == true
1213 | assert minha_funcao(2) == false
1214 |
1215 | # não recomendado - ordem inconsistente
1216 | assert minha_funcao(1) == true
1217 | assert false == minha_funcao(2)
1218 |
1219 | # obrigatório - a asserção é um pattern match
1220 | assert {:ok, expected} = minha_funcao(3)
1221 | ```
1222 |
1223 | ### Guias de Estilo Alternativos
1224 |
1225 | * [Aleksei Magusev's Elixir Style Guide](https://github.com/lexmag/elixir-style-guide#readme)
1226 | — Um guia de estilo Elixir opiniático inspirado nas práticas encontradas
1227 | nas bibliotecas 'core' do Elixir.
1228 | Desenvolvido por [Aleksei Magusev](https://github.com/lexmag) e
1229 | [Andrea Leopardi](https://github.com/whatyouhide), membros da equipe principal do Elixir.
1230 | Apesar do projeto do Elixir não aderir a um guia de estilo específico,
1231 | este é o guia mais próximo de suas convenções.
1232 |
1233 | * [Credo's Elixir Style Guide](https://github.com/rrrene/elixir-style-guide#readme)
1234 | — Guia de Estilo para a linguagem Elixir, implementada pelo
1235 | [Credo](http://credo-ci.org), ferramenta de análise estática de código.
1236 |
1237 | ### Ferramentas
1238 |
1239 | Confira o [Awesome Elixir][Code Analysis] para encontrar bibliotecas e
1240 | ferramentas para te ajudar em análise e linting de código.
1241 |
1242 | ## Participando
1243 |
1244 | ### Contribuindo
1245 |
1246 | Esperamos que este se torne um ponto de encontro para discussões da comunidade
1247 | sobre as melhores práticas em Elixir.
1248 | Sinta-se bem-vindo(a) a abrir issues ou enviar pull requests com melhorias.
1249 | Obrigado desde já por sua ajuda!
1250 |
1251 | Confira as [dicas de contribuição - em inglês][Contribuindo]
1252 | e o [código de conduta][Code Of Conduct] para saber mais.
1253 |
1254 | ### Espalhe
1255 |
1256 | Um guia de estilo de uma comunidade não faz sentido sem o apoio da comunidade.
1257 | Por gentileza tuíte, [dê estrelas][Stargazers] e compartilhe [este guia][Elixir Style Guide] com todos, para que todos possam contribuir.
1258 |
1259 | ## Cópias
1260 |
1261 | ### Licença
1262 |
1263 | 
1264 | Este trabalho é licenciada sob uma
1265 | [Licença Creative Commons Attribution 3.0 Unported][Licença]
1266 |
1267 | ### Atribuição
1268 |
1269 | A estrutura deste guia, alguns trechos de código dos exemplos, e muito pontos
1270 | iniciais deste documento foram empresados do [Guia de Estilo da Comunidade Ruby].
1271 | Muitas coisas se aplicavam ao Elixir e nos permitiram publicar _algum_ documento
1272 | mas rápido e dar início ao projeto.
1273 | out quicker to start the conversation.
1274 |
1275 | Aqui está a [lista das pessoas que gentilmente contribuíram][Contributors] com este
1276 | projeto.
1277 |
1278 |
1279 | [Chinês Tradicional]: https://github.com/elixirtw/elixir_style_guide/blob/master/README_zhTW.md
1280 | [Code Analysis]: https://github.com/h4cc/awesome-elixir#code-analysis
1281 | [Code Of Conduct]: https://github.com/christopheradams/elixir_style_guide/blob/master/CODE_OF_CONDUCT.md
1282 | [Conflicting Aliases]: https://elixirforum.com/t/using-aliases-for-fubar-fubar-named-module/1723
1283 | [Contribuindo]: https://github.com/elixir-lang/elixir/blob/master/CODE_OF_CONDUCT.md
1284 | [Contributors]: https://github.com/christopheradams/elixir_style_guide/graphs/contributors
1285 | [Coreano]: https://github.com/marocchino/elixir_style_guide/blob/new-korean/README-koKR.md
1286 | [Elixir]: http://elixir-lang.org
1287 | [Espanhol]: https://github.com/albertoalmagro/elixir_style_guide/blob/spanish/README_esES.md
1288 | [ExDoc]: https://github.com/elixir-lang/ex_doc
1289 | [ExUnit]: https://hexdocs.pm/ex_unit/ExUnit.html
1290 | [Guard Expressions]: http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses
1291 | [Guia de Estilo Elixir]: https://github.com/christopheradams/elixir_style_guide
1292 | [Hex]: https://hex.pm/packages
1293 | [Inglês]: https://github.com/christopheradams/elixir_style_guide/blob/master/README.md
1294 | [Japonês]: https://github.com/kenichirow/elixir_style_guide/blob/master/README-jaJP.md
1295 | [Licença]: http://creativecommons.org/licenses/by/3.0/deed.en_US
1296 | [Atributos de Módulo]: http://elixir-lang.org/getting-started/module-attributes.html#as-annotations
1297 | [Português]: https://github.com/gusaiani/elixir_style_guide/blob/master/README_ptBR.md
1298 | [Guia de Estilo da Comunidade Ruby]: https://github.com/bbatsov/ruby-style-guide
1299 | [Sentence Spacing]: http://en.wikipedia.org/wiki/Sentence_spacing
1300 | [Stargazers]: Use://github.com/christopheradams/elixir_style_guide/stargazers
1301 |
--------------------------------------------------------------------------------
/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.1.0"
9 | @source_url "https://github.com/christopheradams/elixir_style_guide"
10 |
11 | def project do
12 | [app: :elixir_style_guide,
13 | version: @version,
14 | elixir: "~> 1.0",
15 | build_embedded: Mix.env == :prod,
16 | start_permanent: Mix.env == :prod,
17 | docs: docs(),
18 | description: @project_description,
19 | source_url: @source_url,
20 | package: package(),
21 | deps: deps()]
22 | end
23 |
24 | def application do
25 | [applications: [:logger]]
26 | end
27 |
28 | defp deps do
29 | []
30 | end
31 |
32 | defp docs() do
33 | [
34 | source_ref: "v#{@version}",
35 | main: "readme",
36 | extras: [
37 | "README.md": [title: "README"]
38 | ]
39 | ]
40 | end
41 |
42 | defp package do
43 | [
44 | name: :elixir_style_guide,
45 | maintainers: ["Christopher Adams"],
46 | licenses: ["CC-by"],
47 | links: %{
48 | "GitHub" => @source_url
49 | }
50 | ]
51 | end
52 | end
53 |
--------------------------------------------------------------------------------