Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tutorial Phoenix Framework V2

Arthur
October 22, 2016

Tutorial Phoenix Framework V2

Tutorial de 2 horas apresentado no meetup de python e ruby de Belo Horizonte no dia 22/10/2016. Foram ensinados conceitos de programação funcional, um pouco de Elixir e um pouco do Phoenix Framework

Arthur

October 22, 2016
Tweet

More Decks by Arthur

Other Decks in Programming

Transcript

  1. PRIMEIRA PARTE ELIXIR ▸ Conceitos de programação funcional ▸ IEx

    ▸ Mix ▸ Tipos de dados ▸ Operador Pipe ▸ Módulos e funções nomeadas ▸ Controles de fluxo ▸ Estruturas de repetição
  2. SEGUNDA PARTE PHOENIX FRAMEWORK ▸ Criação do projeto ▸ Estrutura

    de arquivos ▸ Rotas e pipelines ▸ Controllers e Models ▸ Templates e Views ▸ Channels
  3. ELIXIR JOSÉ VALIM ▸ Brasileiro ▸ Fez parte do core

    team do rails ▸ Participou de vários projetos open source ▸ Decidiu criar o Elixir em 2011
  4. PORQUE ERLANG? ▸ Criado 1986 para resolver problemas na área

    de telefonia ▸ Altamente tolerante a falhas ▸ Feito para concorrência e paralelismo. ELIXIR
  5. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL É um paradigma de programação que

    trata a computação como uma avaliação de funções matemáticas e que evita estados ou dados mutáveis. O QUE É PROGRAMAÇÃO FUNCIONAL?
  6. Uma vez que uma variável é criada, seu valor não

    pode mais ser alterado IMUTABILIDADE CONCEITOS DE PROGRAMAÇÃO FUNCIONAL
  7. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL Eshell V8.0.3 1> A = 10.

    10 2> A = 20. ** exception error: no match of right hand side value 20
  8. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL Interactive Elixir (1.3.2) iex(4)> a =

    10 10 iex(5)> ^a = 20 ** (MatchError) no match of right hand side value: 20
  9. REBINDING O valor na memória continua imutável, mas a variável

    pode ser reutilizada CONCEITOS DE PROGRAMAÇÃO FUNCIONAL
  10. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL soma = 25 func_soma = fn

    -> "A soma é #{ soma }" end soma = 100 func_soma.() "A soma é 25"
  11. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL soma = 25 func_soma = ->

    { puts soma } soma = 100 func_soma.() 100
  12. São funções que podem ser tratadas como valores e que

    podem ser manipuladas ou retornadas por outras funções. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL FUNÇÕES ANÔNIMAS
  13. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL soma10 = fn (x) -> x

    + 10 end soma10.(20) => 30 multiplica = fn x,y -> x * y end multiplica.(10,10) => 100 lista = [1,2,3,4,5] Enum.map(lista, soma10) => [11, 12, 13, 14, 15, 16]
  14. ‣ Funções sem efeitos colaterais ‣ Não acessam banco ‣

    Não acessam arquivos ‣ Sempre retornam os mesmos valores para os mesmo parâmetros CONCEITOS DE PROGRAMAÇÃO FUNCIONAL FUNÇÕES PURAS
  15. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL soma10 = fn (x) -> x

    + 10 end soma10.(20) => 30 multiplica = fn x,y -> x * y end multiplica.(10,10) => 100
  16. São funções que recebem ou retornam outras funções CONCEITOS DE

    PROGRAMAÇÃO FUNCIONAL HIGHER ORDER FUNCTIONS
  17. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL lista = [1,2,3,4,5] [1, 2, 3,

    4, 5] Enum.map(lista, fn x -> x * x end) [1, 4, 9, 16, 25] Enum.reduce(lista, 0, fn(x,y) -> x + y end) 15 Enum.reduce(lista, 0, &(&1 + &2)) 15 Enum.filter(lista, fn x -> x > 2 end) [3, 4, 5]
  18. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL add = fn x -> fn

    y -> x + y end end increment = add.(1) increment.(3) => 4
  19. O operador “=“ significa “Faça com que o lado esquerdo

    seja igual ao direito” CONCEITOS DE PROGRAMAÇÃO FUNCIONAL PATTERN MATCHING
  20. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL {a, b, c} = {:hello, "world",

    42} a :hello b "world" {a, _, c} = {:hello, "world", 42} a :hello c 42
  21. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL {a, b, c} = {:hello, “world"}

    ** (MatchError) no match of right hand side value: {:hello, "world"}
  22. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL defmodule Math do def sum_list([head |

    tail], accumulator) do sum_list(tail, head + accumulator) end def sum_list([], accumulator) do accumulator end end IO.puts Math.sum_list([1, 2, 3], 0) 6
  23. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL defmodule Math do def sum_list([head (1)

    | tail ([2,3])], accumulator (0) ) do sum_list(tail([2,3]), head (1) + accumulator (0)) end def sum_list([], accumulator) do accumulator end end IO.puts Math.sum_list([1, 2, 3], 0) 6
  24. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL defmodule Math do def sum_list([head (2)

    | tail ([3])], accumulator (1) ) do sum_list(tail([3]), head (2) + accumulator (1)) end def sum_list([], accumulator) do accumulator end end IO.puts Math.sum_list([1, 2, 3], 0) 6
  25. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL defmodule Math do def sum_list([head (3)

    | tail ([])], accumulator (3) ) do sum_list(tail([]), head (3) + accumulator (3)) end def sum_list([], accumulator) do accumulator end end IO.puts Math.sum_list([1, 2, 3], 0) 6
  26. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL defmodule Math do def sum_list([head |

    tail], accumulator ) do sum_list(tail, head + accumulator) end def sum_list([], accumulator (6) ) do accumulator (6) end end IO.puts Math.sum_list([1, 2, 3], 0) 6
  27. CONCEITOS DE PROGRAMAÇÃO FUNCIONAL defmodule Fatorial do def de(1, acc),

    do: acc def de(n, acc) when n > 0 do de(n-1, acc * n) end end
  28. IEX

  29. MIX

  30. É uma ferramenta que vem junto com o Elixir para

    criar tarefas, compilar código, testar, gerenciar dependências e muito mais. ELIXIR MIX
  31. ELIXIR CRIAÇÃO DE UM NOVO PROJETO › mix new teste

    * creating README.md * creating .gitignore * creating mix.exs * creating config * creating config/config.exs * creating lib * creating lib/teste.ex * creating test * creating test/test_helper.exs * creating test/teste_test.exs Your Mix project was created successfully. You can use "mix" to compile it, test it, and more: cd teste mix test Run "mix help" for more commands.
  32. ELIXIR BAIXAR DEPENDÊNCIAS › mix deps.get Running dependency resolution Dependency

    resolution completed connection: 1.0.4 db_connection: 1.0.0 decimal: 1.2.0 postgrex: 0.12.1 * Getting postgrex (Hex package) Checking package (https://repo.hex.pm/tarballs/postgrex-0.12.1.tar) Using locally cached package * Getting connection (Hex package) Checking package (https://repo.hex.pm/tarballs/connection-1.0.4.tar) Using locally cached package * Getting db_connection (Hex package) Checking package (https://repo.hex.pm/tarballs/db_connection-1.0.0.tar) Using locally cached package * Getting decimal (Hex package) Checking package (https://repo.hex.pm/tarballs/decimal-1.2.0.tar) Using locally cached package
  33. ELIXIR BUSCAR INFORMAÇÕES DE DEPENDÊNCIAS › mix hex.info postgrex PostgreSQL

    driver for Elixir. Config: {:postgrex, "~> 0.12.1"} Releases: 0.12.1, 0.12.0, 0.11.2, 0.11.1, 0.11.0, 0.10.0, 0.9.1, 0.9.0, 0.8.4, 0.8.3, ... Maintainers: Eric Meadows-Jönsson, James Fish Licenses: Apache 2.0 Links: Github: https://github.com/elixir-ecto/postgrex
  34. HEX

  35. 1 # integer 0x1F # integer 1.0 # float true

    # boolean :atom # atom / symbol "elixir" # string 'elixir' # char list [1, 2, 3] # list {1, 2, 3} # tuple ELIXIR TIPOS DE DADOS
  36. lang = "Phyton" if lang == "Elixir" do IO.puts lang

    else IO.puts "Não é elixir" end Não é elixir :ok ELIXIR IF / ELSE
  37. lang = "Elixir" unless lang do IO.puts lang end nil

    lang = "Phyton" unless lang == "Elixir" do IO.puts lang end "Python" ELIXIR UNLESS
  38. cond do 2 + 2 == 5 -> "Falso" 2

    * 2 == 3 -> "Falso" 1 + 1 == 2 -> "Verdadeiro" true -> "Se nada der certo chega aqui" end "Verdadeiro" ELIXIR COND
  39. case {1, 2, 3} do {4, 5, 6} -> "Não

    vai dar match" {1, x, 3} -> "Vai dar match e o x vai receber o valor 2" _ -> "Essa clausula vai dar match em qualquer valor" end "Vai dar match e o x vai receber o valor 2" ELIXIR CASE
  40. case {1, 2, 3} do {4, 5, 6} -> "Não

    vai dar match" {1, ^x, 3} -> "Vai dar match e o x vai receber o valor 2" _ -> "Essa clausula vai dar match em qualquer valor" end "Essa clausula vai dar match em qualquer valor" ELIXIR CASE
  41. calcular = fn expressao -> case expressao do {:+, num1,

    num2} -> num1 + num2 {:-, num1, num2} -> num1 - num2 {:*, num1, num2} -> num1 * num2 {:/, num1, num2} -> num1 / num2 end end calcular.({:+, 2 ,2}) 4 calcular.({:-, 2 ,2}) 0 calcular.({:/, 2 ,0}) ** (ArithmeticError) bad argument in arithmetic expression :erlang./(2, 0) ELIXIR CASE
  42. lista = [1,2,3,4,5] [1, 2, 3, 4, 5] Enum.map(lista, fn

    x -> x * x end) [1, 4, 9, 16, 25] Enum.reduce(lista, 0, fn(x,y) -> x + y end) 15 Enum.reduce(lista, 0, &(&1 + &2)) 15 Enum.filter(lista, fn x -> x > 2 end) [3, 4, 5] ELIXIR ENUM
  43. stream = 1..3 |> Stream.map(&IO.inspect(&1)) |> Stream.map(&(&1 * 2)) |>

    Stream.map(&IO.inspect(&1)) Enum.to_list(stream) 1 2 2 4 3 6 => [2, 4, 6] ELIXIR STREAM
  44. File.stream!("path/to/some/file") |> Flow.from_enumerable() |> Flow.flat_map(fn line -> for word <-

    String.split(" "), do: {word, 1} end) |> Flow.reduce_by_key(& &1 + &2) |> Enum.to_list() ELIXIR FLOW
  45. ELIXIR CHAMANDO FUNÇÕES Para chamar uma função nomeada, a sintaxe

    sempre é: Modulo.funcao(parametro1, parametro2, ..)
  46. defmodule Math do def sum(a, b) do a + b

    end end Math.sum(1,2) => 3 ELIXIR MÓDULOS
  47. defmodule Math do def sum(a, b) do do_sum(a, b) end

    defp do_sum(a, b) do a + b end end IO.puts Math.sum(1, 2) => 3 IO.puts Math.do_sum(1, 2) => ** (UndefinedFunctionError) ELIXIR FUNÇÕES
  48. defmodule Math do def zero?(0), do: true def zero?(x) when

    is_integer(x), do: false end ELIXIR FUNÇÕES
  49. calcular = fn expressao -> case expressao do {:+, num1,

    num2} -> num1 + num2 {:-, num1, num2} -> num1 - num2 {:*, num1, num2} -> num1 * num2 {:/, num1, num2} -> num1 / num2 end end calcular.({:+, 2 ,2}) 4 calcular.({:-, 2 ,2}) 0 calcular.({:/, 2 ,0}) ** (ArithmeticError) bad argument in arithmetic expression :erlang./(2, 0) ELIXIR GUARD CLAUSES
  50. calcular = fn expressao -> case expressao do {:+, num1,

    num2} -> num1 + num2 {:-, num1, num2} -> num1 - num2 {:*, num1, num2} -> num1 * num2 {:/, num1, num2} when num2 != 0 -> num1 / num2 {:/, num1, num2} when num2 == 0 -> IO.puts "Não é possível dividir por 0" end end calcular.({:/, 2, 0}) Não é possível dividir por 0 :ok calcular.({:/, 2, 1}) 2.0 ELIXIR GUARD CLAUSES
  51. Envia o retorno da função anterior como primeiro argumento da

    próxima função. ELIXIR PIPE OPERATOR (|>)
  52. other_function() |> new_function() |> baz() |> bar() |> foo() "Elixir

    rocks" |> String.upcase |> String.split ["ELIXIR", "ROCKS"] "elixir" |> String.ends_with?("ixir") true ELIXIR
  53. PHOENIX FRAMEWORK CHRIS MCCORD ▸ Descobriu Elixir em 2013 ▸

    Desenvolveu uma biblioteca de websockets ▸ Viu a oportunidade de criar um framework com foco em produtividade no estilo do Rails.
  54. TIMELINE Dezembro de 2013: Início do desenvolvimento Setembro de 2014:

    José Valim entra para o time Agosto de 2015: Versão 1.0 Junho de 2016: Versão 1.2 com Phoenix Presence Janeiro de 2017: Versão 1.3 sem models e pasta web PHOENIX FRAMEWORK