Skip to content

Latest commit

 

History

History
1300 lines (1017 loc) · 33.2 KB

README_ptBR.md

File metadata and controls

1300 lines (1017 loc) · 33.2 KB

Índice

Introdução

Arquitetura líquida. É como o jazz - você improvisa, você trabalha junto, você se inspira nos outros, você cria alguma coisa, eles criam alguma coisa.

—Frank Gehry

Estilo é importante. Elixir tem muito estilo, mas como todas as linguagens, ele pode ser estragado. Não estrague o estilo.

O Guia

Este é o guia de estilo da comunidade para a Linguagem de Programação Elixir. Sinta-se à vontade para enviar pull requests e sugestões, e seja parte da vibrante comunidade do Elixir.

Se você está procurando outros projetos para contribuir, por gentileza confira o site do gerenciador de pacotes Hex.

Traduções deste guia estão disponíveis nas seguintes línguas:

Layout do Código Fonte

  • Use dois espaços por nível de recuo. Não use hard tabs. [link]

    # não recomendado - quatro espaços
    def alguma_funcao do
        fazer_algo
    end
    
    # recomendado
    def alguma_funcao do
      fazer_algo
    end
  • Use quebra de linha estilo Unix (*Usuários de BSD/Solaris/Linux/OSX por padrão estão cobertos, usuários Windows tem que tomar muito cuidado). [link]

  • Se você está usando Git talvez você queira adicionar a seguinte configuração para evitar quebras de linha Windows adicionadas acidentalmente: [link]

    git config --global core.autocrlf true
  • Use espaço ao redor de operadores, depois de vírgulas, dois pontos e ponto e vírgulas. Não coloque espaço ao redor de pares correspondentes como parênteses, colchetes e chaves. Espaço pode ser (na maioria das vezes) irrelevante no runtime do Elixir, mas seu uso apropriado é essencial para se escrever código leǵivel. [link]

    soma = 1 + 2
    {a, b} = {2, 3}
    [primeiro | resto] = [1, 2, 3]
    Enum.map(["um", <<"dois">>, "três"], fn num -> IO.puts num end)
  • Não use espaço depois de operadores que não são palavras e recebem um argumento; ou ao redor do operador range. [link]

    0 - 1 == -1
    ^pinned = alguma_funcao()
    5 in 1..10
  • Use linhas em branco entre defs para quebrar uma função em seus parágrafos lógicos. [link]

    def alguma_funcao(algum_dado) do
      dado_alterado = Module.function(algum_dado)
    end
    
    def alguma_funcao do
      resultado
    end
    
    def alguma_outra_funcao do
      outro_resultado
    end
    
    def uma_funcao_mais_longa do
      um
      dois
    
      três
      quatro
    end
  • ...mas coloque junto defs de uma linha só que correspondam à mesma função. [link]

    def alguma_funcao(nil), do: {:err, "Nenhum Valor"}
    def alguma_funcao([]), do: :ok
    def alguma_funcao([primeiro | resto]) do
      alguma_funcao(resto)
    end
  • 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. [link]

    def alguma_funcao(args),
      do: Enum.map(args, fn(arg) -> arg <> " está em uma linha muito longa!" end)

    Quando você usar a convenção acima e tiver mais que uma cláusula usando a sintaxe do:, coloque o do: em uma nova linha para cada cláusula:

    # não recomendado
    def alguma_funcao([]), do: :vazio
    def alguma_funcao(_),
      do: :linha_muito_longa_aqui
    
    # recomendado
    def alguma_funcao([]),
      do: :vazio
    def alguma_funcao(_),
      do: :linha_muito_longa_aqui
  • Se você tiver mais que um def multilinha, não use defs de uma linha. [link]

    def alguma_funcao(nil) do
      {:err, "Nenhum Valor"}
    end
    
    def alguma_funcao([]) do
      :ok
    end
    
    def alguma_funcao([primeiro | resto]) do
      alguma_funcao(resto)
    end
    
    def alguma_funcao([primeiro | resto], opts) do
      alguma_funcao(resto, opts)
    end
  • Use parênteses em funções de aridade um ao usar o operador pipe (|>) [link]

    # não recomendado
    alguma_string |> String.downcase |> String.strip
    
    # recomendado
    alguma_string |> String.downcase() |> String.strip()
  • Use o operador pipe (|>) para encadear funções. [link]

    # não recomendado
    String.strip(String.downcase(alguma_string))
    
    # recomendado
    alguma_string |> String.downcase |> String.strip
    
    # Pipelines multilinha não recebem indentação extra
    alguma_string
    |> String.downcase
    |> String.strip
    
    # Pipelines multilinha do lado direito de um pattern match
    # devem ser indentados em uma nova linha
    string_sanitizada =
      alguma_string
      |> String.downcase
      |> String.strip

    Mesmo este sendo o método recomendado, lembre-se que copiar e colar pipelines multilinha no IEx pode resultar em erro de sintaxe, já que o IEx vai avaliar a primeira linha sem perceber que a próxima linha tem um pipeline.

  • Evite usar o operador pipe uma vez só. [link]

    # não recomendado
    alguma_string |> String.downcase
    
    # recomendado
    String.downcase(alguma_string)
  • Use variáveis sozinhas na primeira parte de uma cadeia de funções. [link]

    # PIOR JEITO!
    # Isto é interpretado como String.strip("não" |> String.downcase).
    String.strip "não" |> String.downcase()
    
    # não recomendado
    String.strip(alguma_string) |> String.downcase() |> String.codepoints()
    
    # recomendado
    alguma_string |> String.strip() |> String.downcase() |> String.codepoints()
  • Ao declarar uma linha que abrange múltiplas linhas, comece a lista em uma nova linha, e indente os elementos para mantê-los alinhados. [link]

    # não recomendado - sem indentação
    lista = [:primeiro_item, :segundo_item, :proximo_item,
    :ultimo_item]
    
    # melhor, mas não recomendado - com indentação
    lista = [:primeiro_item, :segundo_item, :proximo_item,
             :ultimo_item]
    
    # recomendado - lista começa em uma linha própria
    # bom para listas menores
    lista =
      [:primeiro_item, :segundo_item, :proximo_item,
       :ultimo_item]
    
    # também recomendado - com cada elemento em uma linha
    # bom para listas longas, listas com elementos longos ou listas com comentários
    lista = [
      :primeiro_item,
      :segundo_item,
      :proximo_item,
      # comentário
      :muitos_itens,
      :ultimo_item
    ]
  • Evite espaço em branco no fim das linhas [link]

  • Termine todos os arquivos com uma nova linha. [link]

Sintaxe

  • Use parênteses quando um def tiver argumentos, e omita os parênteses quando ele não tiver argumentos. [link]

    # não recomendado
    def alguma_funcao arg1, arg2 do
      # corpo omitido
    end
    
    def alguma_funcao() do
      # corpo omitido
    end
    
    # recomendado
    def alguma_funcao(arg1, arg2) do
      # corpo omitido
    end
    
    def alguma_funcao do
      # corpo omitido
    end
  • Adicione uma linha em branco após uma declaração multilinha sinalizando que a declaração terminou. [link]

    # não recomendado
    alguma_string =
      "Oi"
      |> String.downcase
      |> String.strip
    outra_string <> alguma_string
    
    # recomendado
    alguma_string =
      "Oi"
      |> String.downcase
      |> String.strip
    
    outra_string <> alguma_string
    # também não recomendado
    alguma_coisa =
      if x == 2 do
        "Oi"
      else
        "Tchau"
      end
    String.downcase(alguma_coisa)
    
    # recomendado
    alguma_coisa =
      if x == 2 do
        "Oi"
      else
        "Tchau"
      end
    
    String.downcase(alguma_coisa)
  • Nunca use do: para if ou unless multilinha. [link]

    # não recomendado
    if alguma_condicao, do:
      # uma linha de código
      # outra linha de código
      # note que este bloco não tem end
    
    # recomendado
    if alguma_condicao do
      # algumas
      # linhas
      # de código
    end
  • Use do: para if/unless de uma linha só. [link]

    # recomendado
    if alguma_condicao, do: # alguma_coisa
    
  • Nunca use unless com else. Reescreva estes com apenas casos positivos. [link]

    # não recomendado
    unless successo? do
      IO.puts 'falha'
    else
      IO.puts 'successo'
    end
    
    # recomendado
    if successo? do
      IO.puts 'successo'
    else
      IO.puts 'falha'
    end
  • Use true como a última condição do cond quando você precisa de uma cláusula que sempre dê match. [link]

    # não recomendado
    cond do
      1 + 2 == 5 ->
        "Não"
      1 + 3 == 5 ->
        "Oh, oh"
      :else ->
        "OK"
    end
    
    # recomendado
    cond do
      1 + 2 == 5 ->
        "Não"
      1 + 3 == 5 ->
        "Oh, oh"
      true ->
        "OK"
    end
  • Nunca coloque um espaço entre o nome da função e a abertura dos parênteses. [link]

    # não recomendado
    f (3 + 2) + 1
    
    # recomendado
    f(3 + 2) + 1
  • Use parênteses em chamadas de função, especialmente dentro de uma pipeline. [link]

    # não recomendado
    f 3
    
    # recomendado
    f(3)
    
    # não recomendado e é convertido como rem(2, (3 |> g)), que não é o que você quer.
    2 |> rem 3 |> g
    
    # recomendado
    2 |> rem(3) |> g
  • Omita parênteses em chamadas de macro onde um bloco do é passado. [link]

    # não recomendado
    quote(do
      foo
    end)
    
    # recomendado
    quote do
      foo
    end
  • Parênteses são opcionais em chamadas de função (fora de pipelines) quando o último argumento é uma expressão de função. [link]

    # recomendado
    Enum.reduce(1..10, 0, fn x, acc ->
      x + acc
    end)
    
    # também recomendado
    Enum.reduce 1..10, 0, fn x, acc ->
      x + acc
    end
  • Use parênteses quando chamar funções de aridade zero, para que elas fiquem distintas de variáveis. A partir do Elixir 1.4 o compilador vai emitir warnings em lugares onde esta ambiguidade existir. [link]

    defp fazer_algo, do: ...
    
    # não recomendado
    def minha_funcao do
      fazer_algo # isto é uma variável ou uma chamada de função?
    end
    
    # recomendado
    def minha_funcao do
      fazer_algo() # isto claramente é uma chamada de função
    end
  • Sempre use a sintaxe simplificada para listas de palavras-chave. [link]

    # não recomendado
    algum_valor = [{:a, "baz"}, {:b, "qux"}]
    
    # recomendado
    algum_valor = [a: "baz", b: "qux"]
  • Omita colchetes de listas de palavras-chave sempre que eles forem opcionais. [link]

    # não recomendado
    alguma_funcao(foo, bar, [a: "baz", b: "qux"])
    
    # recomendado
    alguma_funcao(foo, bar, a: "baz", b: "qux")
  • Indente e alinhe cláusulas with sucessivas. Coloque o argumento do: em uma nova linha, indentada normalmente. [link]

    with {:ok, foo} <- fetch(opts, :foo),
         {:ok, bar} <- fetch(opts, :bar),
      do: {:ok, foo, bar}
  • Se a expressão with tiver um bloco do com mais de uma linha, ou tem uma opção else, use a sintaxe multilinha. [link]

    with {:ok, foo} <- fetch(opts, :foo),
         {:ok, bar} <- fetch(opts, :bar) do
      {:ok, foo, bar}
    else
      :error ->
        {:error, :bad_arg}
    end

Nomenclatura

  • Use snake_case para átomos, funções e variáveis. [link]

    # não recomendado
    :"algum átomo"
    :AlgumAtomo
    :algumAtomo
    
    algumaVar = 5
    
    def algumaFuncao do
      ...
    end
    
    def AlgumaFuncao do
      ...
    end
    
    # recomendado
    :algum_atom
    
    alguma_var = 5
    
    def alguma_funcao do
      ...
    end
  • Use CamelCase para módulos (mantenha siglas como HTTP, RFC, XML em maiúsculo). [link]

    # não recomendado
    defmodule Algummodulo do
      ...
    end
    
    defmodule Algum_Modulo do
      ...
    end
    
    defmodule AlgumXml do
      ...
    end
    
    # recomendado
    defmodule AlgumModulo do
      ...
    end
    
    defmodule AlgumXML do
      ...
    end
  • Os nomes das macros com predicado (funções geradas na hora da compilação que retornam um valor booleano) que podem ser usadas dentro de guards devem ser prefixados com is_. Para uma lista de expressões permitidas, veja nos documentos Guard. [link]

    defmacro is_cool(var) do
      quote do: unquote(var) == "cool"
    end
  • Os nomes de funções com predicados que não podem ser usadas em guards devem ter um ponto de interrogação à direita (?) em vez do prefixo is_ (ou similar). [link]

    def cool?(var) do
      # Verificação complexa se var for cool não é possível em uma função pura.
    end
  • Funções privadas com o mesmo nome de funções públicas devem começar com do_. [link]

    def soma(list), do: do_soma(list, 0)
    
    # funções privadas
    defp do_soma([], total), do: total
    defp do_soma([head | tail], total), do: do_soma(tail, head + total)

Comentários

  • Escreva código expressivo e busque transmitir a intenção do seu programa através de fluxo de controle, estrutura e nomenclaturas. [link]

  • Use um espaço entre o # do comentário e o texto do comentário. [link]

    String.first(alguma_string) #não recomendado
    String.first(alguma_string) # recomendado
  • Comentários de mais de uma palavra começam com maiúscula, e frases recebem pontuação. Use um espaço depois dos pontos finais. [link]

    # não recomendado
    # este comentário em minúsculas não tem pontuação
    
    # recomendado
    # Exemplo com maiúscula
    # Use pontuação em frases completas.

Anotações em Comentários

  • Anotações normalmente devem vir na linha imediatamente acima do respectivo código. [link]

  • A palavra-chave de anotação é inteira em maiúsculas, seguida por dois-pontos e espaço, e então uma descrição do problema. [link]

    # TODO: Deprecate in v2.0.
    def alguma_funcao(arg), do: {:ok, arg}
  • Nos casos em que o problema é tão óbvio que qualquer documentação seria redundante, as anotações podem vir no fim da linha em questão sem comentário adicional. Esta forma deve ser a exceção e não a regra. [link]

    start_task()
    Process.sleep(5000) # FIXME
  • Use TODO para anotar funcionalidades que faltam ou funcionalidades que devem ser acrescentadas no futuro. [link]

  • Use FIXME para anotar código quebrado que precisa ser corrigido. [link]

  • Use OPTIMIZE para anotar código lento ou ineficiente que pode causar problemas de desempenho. [link]

  • Use HACK para anotar lugares onde existem práticas questionáveis e que deveriam ser refatoradas. [link]

  • Use REVIEW para anotar qualquer coisa que precise ser revista para confirmar que está funcionando conforme pretendido. Exemplo: REVIEW: Temos certeza que é assim que o cliente faz X hoje em dia? [link]

  • Use outras palavras-chave customizadas se apropriado, mas se certifique de documentá-las no README do seu projeto ou algo similar. [link]

Módulos

  • Use um módulo por arquivo, a não ser que o módulo seja usado apenas internamente por outro módulo (um teste, por exemplo). [link]

  • Use nomes de arquivo em snake_case e nomes de módulo emCamelCase. [link]

    # arquivo chamado algum_modulo.ex
    
    defmodule AlgumModulo do
    end
  • Expresse cada nível de aninhamento em um nome de módulo como um diretório. [link]

    # arquivo chamado parser/core/xml_parser.ex
    
    defmodule Parser.Core.XMLParser do
    end
  • Não use uma linha em branco após um defmodule. [link]

  • Use uma linha em branco após blocos de código em módulos. [link]

  • Liste atributos e diretivas de módulo na seguinte ordem: [link]

    1. @moduledoc
    2. @behaviour
    3. use
    4. import
    5. alias
    6. require
    7. defstruct
    8. @type
    9. @module_attribute
    10. @callback
    11. @macrocallback
    12. @optional_callbacks

    Adicione uma linha em branco entre cada agrupamento, e ordene os termos (como nomes de módulos) alfabeticamente. Abaixo um exemplo geral de como você deve ordenar as coisas em seus módulos:

    defmodule MeuModulo do
      @moduledoc """
      Exemplo de módulo
      """
    
      @behaviour MeuBehaviour
    
      use GenServer
    
      import AlgumaCoisa
      import OutraCoisa
    
      alias Meu.Nome.Comprido.Modulo
      alias Meu.Outro.Exemplo.Modulo
    
      require Integer
    
      defstruct name: nil, params: []
    
      @type params :: [{binary, binary}]
    
      @module_attribute :foo
      @other_attribute 100
    
      @callback alguma_funcao(termo) :: :ok | {:error, termo}
    
      @macrocallback nome_macro(termo) :: Macro.t
    
      @optional_callbacks nome_macro: 1
    
      ...
    end
  • Use a pseudo variável __MODULE__ quando um módulo se referir a si mesmo. Isto previne que tenhamos que atualizar auto-referências quando o nome do módulo mudar. [link]

    defmodule AlgumProjeto.AlgumModulo do
      defstruct [:nome]
    
      def nome(%__MODULE__{nome: nome}), do: nome
    end
  • Se você quiser um nome mais bonito para uma auto-referência de módulo, crie um alias. [link]

    defmodule AlgumProjeto.AlgumModulo do
      alias __MODULE__, as: AlgumModulo
    
      defstruct [:nome]
    
      def nome(%AlgumModulo{nome: nome}), do: nome
    end
  • Evite repetir fragmentos em nomes e namespaces de módulos. Isto melhora a legibilidade e elimina aliases ambíguos. [link]

    # não recomendado
    defmodule Todo.Todo do
      ...
    end
    
    # recomendado
    defmodule Todo.Item do
      ...
    end

Documentação

Documentação em Elixir (quando lida seja no iex com h seja gerada com ExDoc) usa os Atributos de Módulo @moduledoc e @doc.

  • Inclua sempre um atributo @moduledoc na linha imediatamente posterior ao defmodule em seu módulo. [link]

    # não recomendado
    
    defmodule AlgumModulo do
    
      @moduledoc """
      Informação sobre o módulo.
      """
      ...
    end
    
    defmodule OutroModulo do
      use AlgumModulo
      @moduledoc """
      Informação sobre o módulo.
      """
      ...
    end
    
    # recomendado
    
    defmodule AlgumModulo do
      @moduledoc """
      Informação sobre o módulo.
      """
      ...
    end
  • Use @moduledoc false se você não pretende documentar o módulo. [link]

    defmodule AlgumModulo do
      @moduledoc false
      ...
    end
  • Separe o código que vem depois do @moduledoc com uma linha em branco. [link]

    # não recomendado
    
    defmodule AlgumModulo do
      @moduledoc """
      Informação sobre o módulo.
      """
      use OutroModulo
    end
    
    # recomendado
    defmodule AlgumModulo do
      @moduledoc """
      Informação sobre o módulo.
      """
    
      use OutroModulo
    end
  • Use heredocs com markdown na documentação. [link]

    # não recomendado
    
    defmodule AlgumModulo do
      @moduledoc "Informação sobre o módulo."
    end
    
    defmodule AlgumModulo do
      @moduledoc """
      Informação sobre o módulo.
    
      Exemplos:
      iex> AlgumModulo.alguma_funcao
      :resultado
      """
    end
    
    # recomendado
    defmodule AlgumModulo do
      @moduledoc """
      Informação sobre o módulo.
    
      ## Exemplos
    
          iex> AlgumModulo.alguma_funcao
          :resultado
      """
    end

Typespecs

Typespecs são notações para declarar tipos e especificações, para documentação ou para o Dialyzer (ferramenta de análise estática).

Tipos customizados devem ser definidos no topo do módulo com as outras diretivas (veja Módulos).

  • Aplique definições @typedoc e @type juntas, e separe cada par com uma linha em branco. [link]

    defmodule AlgumModulo do
      @moduledoc false
    
      @typedoc "O nome"
      @type name :: atom
    
      @typedoc "O resultado"
      @type result :: {:ok, termo} | {:error, termo}
    
      ...
    end
  • Se um tipo de união for longo demais para caber em um só linha, adicione uma nova linha e indente com espaços para alinhar os tipos. [link]

    # não recomendado - sem indentação
    @type tipo_de_uniao_longo :: algum_tipo | outro_tipo | algum_outro_tipo |
    um_ultimo_tipo
    
    # recomendado
    @type tipo_de_uniao_longo :: algum_tipo | outro_tipo | algum_outro_tipo |
                                 um_ultimo_tipo
    
    # também recomendado - um tipo por linha
    @type tipo_de_uniao_longo :: algum_tipo |
                                 outro_tipo |
                                 algum_outro_tipo |
                                 um_ultimo_tipo
  • Nomeie como t o tipo principal de um módulo, por exemplo: a especificação de tipo para um struct. [link]

    defstruct nome: nil, params: []
    
    @type t :: %__MODULE__{
      nome: String.t | nil,
      params: Keyword.t
    }
  • Escreva especificações logo acima da definicação de uma função, sem separá-los com linha em branco. [link]

    @spec alguma_funcao(termo) :: result
    def alguma_funcao(algum_dado) do
      {:ok, algum_dado}
    end

Structs

  • Use uma lista de átomos para campos de struct que tenham default de nil, seguidos por outras palavras-chave. [link]

    # não recomendado
    defstruct nome: nil, params: nil, ativo: true
    
    # recomendado
    defstruct [:nome, :params, ativo: true]
  • Omita colchetes quando o argumento de um defstruct for uma lista de palavras-chave. [link]

    # não recomendado
    defstruct [params: [], ativo: true]
    
    # recomendado
    defstruct params: [], ativo: true
    
    # obrigatório - colchetes não são opcionais, com ao menos um átomo na lista
    defstruct [:nome, params: [], ativo: true]
  • Indente linhas adicionais de defstruct, mantendo as primeiras chaves alinhadas. aligned. [link]

    defstruct foo: "teste", bar: true, baz: false,
              qux: false, quux: 1

Exceções

  • Adicione o sufixo Error aos nomes de exceções. [link]

    # não recomendado
    defmodule BadHTTPCode do
      defexception [:mensagem]
    end
    
    defmodule BadHTTPCodeException do
      defexception [:mensagem]
    end
    
    # recomendado
    defmodule BadHTTPCodeError do
      defexception [:mensagem]
    end
  • Use minúsculas em mensagens de erro quando emitindo exceções, sem pontuação ao final. [link]

    # não recomendado
    raise ArgumentError, "Isto não é válido."
    
    # recomendado
    raise ArgumentError, "isto é válido"

Coleções

A secão de Coleções do guia ainda não foi adicionada.

Strings

  • Dê match em strings usando o concatenador de strings, e não padrões binários. [link]

    # não recomendado
    <<"minha"::utf8, _resto>> = "minha string"
    
    # recomendado
    "minha" <> _resto = "minha string"

Expressões Regulares

A secão de Coleções do guia ainda não foi adicionada.

Metaprogramação

  • Evite metaprogramação desnecessária. [link]

Testes

  • Ao escrever asserções ExUnit, mantenha a consistência entre a ordem dos valores esperados e reais que estão sob teste. Prefira usar o resultado esperado à direita, a não ser que a asserção seja um pattern match. [link]

    # recomendado - resultado esperado à direita
    assert minha_funcao(1) == true
    assert minha_funcao(2) == false
    
    # não recomendado - ordem inconsistente
    assert minha_funcao(1) == true
    assert false == minha_funcao(2)
    
    # obrigatório - a asserção é um pattern match
    assert {:ok, expected} = minha_funcao(3)

Guias de Estilo Alternativos

  • Aleksei Magusev's Elixir Style Guide — Um guia de estilo Elixir opiniático inspirado nas práticas encontradas nas bibliotecas 'core' do Elixir. Desenvolvido por Aleksei Magusev e Andrea Leopardi, membros da equipe principal do Elixir. Apesar do projeto do Elixir não aderir a um guia de estilo específico, este é o guia mais próximo de suas convenções.

  • Credo's Elixir Style Guide — Guia de Estilo para a linguagem Elixir, implementada pelo Credo, ferramenta de análise estática de código.

Ferramentas

Confira o Awesome Elixir para encontrar bibliotecas e ferramentas para te ajudar em análise e linting de código.

Participando

Contribuindo

Esperamos que este se torne um ponto de encontro para discussões da comunidade sobre as melhores práticas em Elixir. Sinta-se bem-vindo(a) a abrir issues ou enviar pull requests com melhorias. Obrigado desde já por sua ajuda!

Confira as dicas de contribuição - em inglês e o código de conduta para saber mais.

Espalhe

Um guia de estilo de uma comunidade não faz sentido sem o apoio da comunidade. Por gentileza tuíte, dê estrelas e compartilhe [este guia][Elixir Style Guide] com todos, para que todos possam contribuir.

Cópias

Licença

Licença Creative Commons Este trabalho é licenciada sob uma Licença Creative Commons Attribution 3.0 Unported

Atribuição

A estrutura deste guia, alguns trechos de código dos exemplos, e muito pontos iniciais deste documento foram empresados do Guia de Estilo da Comunidade Ruby. Muitas coisas se aplicavam ao Elixir e nos permitiram publicar algum documento mas rápido e dar início ao projeto. out quicker to start the conversation.

Aqui está a lista das pessoas que gentilmente contribuíram com este projeto.