Skip to content

Instantly share code, notes, and snippets.

@jeferson-sb
Last active April 7, 2022 20:55
Show Gist options
  • Save jeferson-sb/f6c26acaa45b16708f2b275063859145 to your computer and use it in GitHub Desktop.
Save jeferson-sb/f6c26acaa45b16708f2b275063859145 to your computer and use it in GitHub Desktop.

Revisions

  1. jeferson-sb revised this gist Apr 7, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -91,7 +91,7 @@ end
    Nós também podemos fazer pattern matching nas conditions.

    ```ex
    case File.lstat do
    case File.lstat "." do
    {:ok, %{type: :regular}} -> "File"
    {:ok, %{type: :directory}} -> "Directory"
    {:error, reason} -> reason
  2. jeferson-sb revised this gist Apr 7, 2022. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -79,7 +79,7 @@ end

    ## `case`

    Permite que você teste um **valor** em uma série de pattern e executa o código do primeiro match encontrado.
    Permite que você teste um **valor** em uma série de patterns e executa o código do primeiro match encontrado.

    ```ex
    case File.open('./text.txt') do
    @@ -120,7 +120,7 @@ defmodule User do
    end
    ```

    ```
    ```ex
    defmodule FizzBuzz do
    def upto(number) when number > 0,
    do: 1..number |> Enum.map(fn n -> fizzbuzz(rem(n, 5), rem(n, 3), n) end)
    @@ -150,6 +150,8 @@ cake = %{flavor: "carrot", cream_cheese: true, cook_time: 30, prep_time: 20}
    with {:ok, cook_time} <- Map.fetch(cake, :cook_time),
    {:ok, prep_time} <- Map.fetch(cake, :prep_time),
    do: cook_time + prep_time

    iex> 50
    ```

    ## Exceptions
    @@ -181,3 +183,8 @@ exit(:failed)
    ```

    Normalmente erros devem ser propagados e tratados por um supervisor, portanto exceptions não são utilizadas com muita frequência.

    Docs / Referências:
    - Livro - Programming Elixir 1.6
    - https://elixir-lang.org/getting-started/case-cond-and-if.html
    - https://elixirschool.com/en/lessons/basics/control_structures
  3. jeferson-sb revised this gist Apr 7, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    Diferente de linguagens tradicionais, Elixir já é capaz de fazer muito apenas fazendo pattern matching de pequenas funções com pattern matching de maneira declarativa. Além disso também fornece algumas estruturas de controle como veremos a seguir:
    Diferente de linguagens tradicionais, Elixir já é capaz de fazer muito apenas fazendo pattern matching de pequenas funções com guard clauses de maneira declarativa. Além disso também fornece algumas estruturas de controle como veremos a seguir:

    # `if` and `unless`

  4. jeferson-sb created this gist Apr 7, 2022.
    183 changes: 183 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,183 @@
    Diferente de linguagens tradicionais, Elixir já é capaz de fazer muito apenas fazendo pattern matching de pequenas funções com pattern matching de maneira declarativa. Além disso também fornece algumas estruturas de controle como veremos a seguir:

    # `if` and `unless`

    ## `if`

    ```ex
    if condition, do: "true", else: "false"
    ```

    Quando a condição é satisfeita, o corpo do if é executado, caso contrário, ele retorna `nil` ou o bloco de código dentro do `else`.

    Forma mais verbosa:

    ```ex
    if x > y do
    "yes"
    else
    "no"
    end
    ```

    Syntax sugar:

    ```ex
    iex> if x > y, do: :true, else: :false
    ```

    ## `unless`

    `unless` também aceita uma condição, porém contrário ao `if` o corpo do código só executado quando a condição é falsy

    ```ex
    unless condition, do: expression, else: expression
    ```

    ```ex
    iex> unless false, do: :ok, else: "error"
    ```

    ```ex
    unless something do
    calc()
    else
    {:error, "something went wrong"}
    end
    ```

    ## `cond`

    Macro que permite que você faça o match de multiplas condições, algo perto de um `else if` em outras linguagens.

    A primeira condição que é satifesta/truthy é executada logo em seguida. Em caso de não houver nenhum match elixir dispara uma exceção/erro.

    ```ex
    cond do
    condition -> code
    condition -> code
    # ...
    end
    ```

    ### Example

    ```ex
    defmodule FizzBuzz do
    def upto(number) when number > 0, do: 1..number |> Enum.map(&fizzbuzz/1)

    defp fizzbuzz(term) do
    cond do
    rem(term, 3) == 0 and rem(term, 5) == 0 -> "FizzBuzz"
    rem(term, 3) == 0 -> "Fizz"
    rem(term, 5) == 0 -> "Buzz"
    true -> term
    end
    end
    end
    ```

    ## `case`

    Permite que você teste um **valor** em uma série de pattern e executa o código do primeiro match encontrado.

    ```ex
    case File.open('./text.txt') do
    {:ok, file} -> file
    {:error, reason} -> "uh-oh"
    end
    ```

    Nós também podemos fazer pattern matching nas conditions.

    ```ex
    case File.lstat do
    {:ok, %{type: :regular}} -> "File"
    {:ok, %{type: :directory}} -> "Directory"
    {:error, reason} -> reason
    end
    ```

    ### Examples

    ```ex
    defmodule ProjectFile do
    def readline(path) do
    case File.open(path, [:read, :utf8]) do
    {:ok, file} -> IO.puts("First line: #{IO.read(file, :line)}")
    {:error, reason} -> IO.puts("Failed to open file: #{reason}")
    end
    end
    end

    defmodule User do
    def can_vote(person) do
    case person do
    person = %{age: age} when is_number(age) and age >= 18 -> true
    _ -> false
    end
    end
    end
    ```

    ```
    defmodule FizzBuzz do
    def upto(number) when number > 0,
    do: 1..number |> Enum.map(fn n -> fizzbuzz(rem(n, 5), rem(n, 3), n) end)
    defp fizzbuzz(x, y, z) do
    case [x, y, z] do
    [0, 0, _] -> "FizzBuzz"
    [_, 0, _] -> "Fizz"
    [0, _, _] -> "Buzz"
    [_, _, _] -> z
    end
    end
    end
    ```

    ## Bonus

    ### `with`

    `case > case`

    Utilizado para combinar o matching de várias clauses ao mesmo tempo e retornar um único resultado.

    ```ex
    cake = %{flavor: "carrot", cream_cheese: true, cook_time: 30, prep_time: 20}

    with {:ok, cook_time} <- Map.fetch(cake, :cook_time),
    {:ok, prep_time} <- Map.fetch(cake, :prep_time),
    do: cook_time + prep_time
    ```

    ## Exceptions

    Exceptions para coisas excepcionais como quando uma database falha ou um servidor cai.

    -> `raise "Something bad"`

    <- (RuntimeError) Something bad

    `raise RuntimeError, message: "this will never match"`

    Tratamento de exceções:

    ```ex
    try do
    1 / 0
    rescue
    ArithmeticError -> IO.puts "Cannot divide by zero"
    end
    ```

    ```ex
    throw({:error, "something"})
    ```

    ```ex
    exit(:failed)
    ```

    Normalmente erros devem ser propagados e tratados por um supervisor, portanto exceptions não são utilizadas com muita frequência.