Funções nomeadas
A função é o principal elemento das linguagens funcionais (grande surpresa an?) e tem como objetivo realizar comportamentos.
Aridade De forma simples, a aridade é a quantidade de argumentos que uma função recebe.
Uma função login
que recebe user
e password
por parâmetro tem aridade 2 e é representado com o nome da função, barra (/) e o número da aridade. Exemplo:
login(user, password) -> login/2
Veja mais no capítulo de Aridade
Funções nomeadas devem existir somente dentro de módulos e são declaradas com def/2
e defp/2
para funções privadas. Como por exemplo:
Vamos criar um novo teste em nosso projeto onde iremos fazer uma soma simples. Na pasta test
crie um novo arquivo chamado math_test.exs
e nele utilizaremos nosso primeiro describe
, descrevendo o que está sendo testado.
Describe
O describe/2
descreve um grupo de testes que tem correlação. Assim podemos criar diversos cenários para uma mesma função que está sendo testada. Exemplo:
Quando a função x funciona
Quando a função x não funciona devido a parâmetros errados
Normalmente o describe recebe o module + função sendo testada + aridade
Podemos tirar algumas vantagens quando utilizamos describe. Uma delas é servir de documentação. Então vamos pensar. Precisamos fazer uma soma (função) e essa soma irá somar dois valores x e y (parâmetros). Analisando isso, podemos presumir que o contrato de nossa função seja algo assim Math.sum/2
. Vamos adicionar isso a nossa describe para facilitar o entendimento
Criaremos o primeiro bloco de teste para quando passarmos os parâmetros corretos.
Parâmetros
Forma de injetar dados dentro de funções de forma a poder ser usada la dentro. A assinatura se da a criação da função usando def/2
, definindo o nome da função e em seguida adicionando parênteses. Dentro dos parênteses adicionamos as variáveis posicionais.
def nome_da_funcao(parametro_1, parametro_2)
Assim você poderá passar dados para dentro da função e os usa-los lá.
nome_da_funcao(5, 10)
Vamos adicionar ao código o bloco de teste usando a função test/2
Precisamos agora entender o que seria um teste bem sucedido aqui e para isso devemos seguir algumas etapas do TDD para se tornar mais simples
Configurar o teste
Executar a chamada
Criar afirmações
Para configurar o teste, precisamos da função a ser chamada e dos parâmetros que queremos passar, então executamos essa função com os parâmetros e guardados sua resposta, para podermos utilizarmos em nossas afirmações.
Pelo básico, Queremos a soma do valor x = 1
e y = 7
e a resposta deve ser 8. Vamos converter isso para o código
Vamos rodar isso e ver o relatório
Possuímos nosso primeiro erro. Decidimos usar TDD e o teste vem antes do código a ser testado, então, não possuímos o código e o teste avisou isso para nós. Math.sum/2 is undefined
. Vamos criar o módulo Math com a função sum com 2 de aridade.
TDD
Testing driven design tem como regra guiar nosso código iniciando ele pelos testes. Uma vez que ele falhe temos um ponto de ação a fazer. Sempre focando no menor esforço a se fazer para o teste passar. Leia mais sobre
Crie o novo arquivo e adicione o mínimo necessários para seguirmos em frente.
Utilizando prefixo underline (_)
Quando temos parâmetros e não o utilizamos, o interpretador nos emite um aviso dizendo que a variável não está sendo utilizada.
warning: variable "y" is unused (if the variable is not meant to be used, prefix it with an underscore) lib/math.ex:2: Math.sum/2
Para esse aviso sumir, podemos colocar como prefixo o underline (_) e ele irá ignorar essa validação.
def sum (_x, _y) do
Salve o arquivo e vamos tentar rodar o teste mais uma vez
Temos um erro diferente (progresso!). O relatório nos conta que o lado esquerdo de nossa assertion está nil
, mas o lado direito esperava 8
. Nossa função não esta retornando nada. Podemos ler assim: o resultado da função esta nulo enquanto o esperado no teste é 8.
Agora podemos implementar nosso código real. Vamos fazer a soma e retornar o valor.
Não precisamos de nenhuma palavra chave para indicar que um valor vai ser retornado na função. Elixir faz isso na última linha da função.
Basta agora rodar o teste e ver tudo funcionar.
Conclusão
Vimos o básico de funções. Descobrimos que uma função é definida por seu nome e sua aridade. Que toda função nomeada deve estar dentro de um módulo e que podemos passar dados para dentro dela usando parâmetros posicionais.
Entendemos um pouco mais sobre TDD e criamos nosso primeiro teste do zero.
Last updated