Percursos
/
Elixir
Elixir
/
Exercícios
/
Underflow da pilha
Underflow da pilha

Underflow da pilha

Exercício de aprendizagem

Introdução

Exceções

Todos os erros em Elixir implementam o comportamento Exception. Tal como o comportamento Access, o comportamento Exception define funções de callback que um módulo tem de implementar para cumprir o contrato de software do comportamento. Assim que um erro é definido, tem as seguintes propriedades:

  • O nome do módulo define o nome do erro.
  • O módulo define uma estrutura de erro.
  • A estrutura terá um campo :message.
  • O módulo pode ser usado com raise/1 e raise/2 para lançar o erro pretendido

O comportamento Exception também especifica dois callbacks: message/1 e exception/1. Se não forem implementadas, serão usadas implementações predefinidas. message/1 transforma a estrutura de erro numa mensagem legível quando é chamada com raise. exception/1 permite adicionar contexto adicional à mensagem quando é chamada com raise/2

Definir uma exceção

Para definir uma exceção a partir de um módulo de erro, usamos a macro defexception:

# Defines a minimal error, with the name `MyError`
defmodule MyError do
  defexception message: "error"
end

# Defines an error with a customized exception/1 function
defmodule MyCustomizedError do
  defexception message: "custom error"

  @impl true
  def exception(value) do
    case value do
      [] ->
        %MyCustomizedError{}

      _ ->
        %MyCustomizedError{message: "Alert: " <> value}
    end
  end
end

Utilizar exceções

Os erros definidos podem ser usados como um erro incorporado, utilizando raise/1 ou raise/2.

  • raise/1 lança um erro específico pelo nome do módulo ou, se o argumento for uma string, lança um RuntimeError com a string como mensagem.
  • raise/2 lança um erro específico pelo nome do módulo e aceita um argumento de atributos que é usado para obter o erro com a mensagem apropriada.

Instruções

Enquanto continuas o teu trabalho na Instruments of Texas, estão a ser feitos progressos na implementação em Elixir da calculadora RPN. A tua equipa gostaria de poder lançar erros mais específicos do que os erros genéricos fornecidos pela biblioteca padrão. Estás a fazer alguma investigação, mas decidiste implementar dois novos erros que implementam o Exception Behaviour.

1. Erro de divisão por zero

Dividir um número por zero produz um resultado indefinido, que a equipa decide ser melhor representado por um erro.

Implementa o módulo DivisionByZeroError com a mensagem de erro: "division by zero occurred"

raise DivisionByZeroError
# => ** (DivisionByZeroError) division by zero occurred

2. Erro quando ocorre um underflow da pilha

As calculadoras RPN usam uma pilha para acompanhar os números antes de serem adicionados. A equipa representa esta pilha com uma lista de números (inteiros e de vírgula flutuante), por exemplo: [3, 4.0]. Cada operação precisa de um número específico de números na pilha para realizar o seu cálculo. Quando não há números suficientes na pilha, isto chama-se um erro de underflow da pilha. Implementa a exceção StackUnderflowError, que fornece uma mensagem predefinida e contexto extra opcional.

raise StackUnderflowError
# => ** (StackUnderflowError) stack underflow occurred

raise StackUnderflowError, "when dividing"
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing

3. Escreve uma função de divisão

Implementa a função divide/1, que recebe uma pilha (uma lista de dois números) e:

  • lança um erro de underflow da pilha quando a pilha não contém números suficientes
  • lança um erro de divisão por zero quando o divisor é 0 (repara que a pilha de números está guardada por ordem inversa)
  • realiza a divisão quando não é lançado nenhum erro
RPNCalculator.Exception.divide([])
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing

RPNCalculator.Exception.divide([0, 100])
# => ** (DivisionByZeroError) division by zero occurred

RPNCalculator.Exception.divide([4, 16])
# => 4

Repara que a ordem da lista está invertida!

Editar via GitHub A ligação abre numa nova janela ou separador
Elixir Exercism

Estás pronto para começar Underflow da pilha?

Inscreve-te no Exercism para aprenderes e dominares Elixir com 58 conceitos168 exercícios, e mentoria humana real, tudo grátis.