Tracks
/
Elixir
Elixir
/
Ejercicios
/
Subdesbordamiento de pila
Subdesbordamiento de pila

Subdesbordamiento de pila

Ejercicio de aprendizaje

Introducción

Excepciones

Todos los errores en Elixir implementan el Comportamiento Exception. Al igual que el Comportamiento Access, el Comportamiento Exception define funciones de callback que un módulo debe implementar para cumplir con el contrato de software del comportamiento. Una vez que se define un error, tiene las siguientes propiedades:

  • El nombre del módulo define el nombre del error.
  • El módulo define una estructura de error.
  • La estructura tendrá un campo :message.
  • El módulo se puede usar con raise/1 y raise/2 para lanzar el error deseado.

El Comportamiento Exception también especifica dos callbacks: message/1 y exception/1. Si no se implementan, se usarán implementaciones por defecto. message/1 transforma la estructura de error en un mensaje legible cuando se llama con raise. exception/1 permite agregar contexto adicional al mensaje cuando se llama con raise/2.

Definir una excepción

Para definir una excepción a partir de un módulo de error, usamos la 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

Usar excepciones

Los errores definidos se pueden usar como un error incorporado usando raise/1 o raise/2.

  • raise/1 lanza un error específico por su nombre de módulo, o, si el argumento es un string, lanzará un RuntimeError con el string como mensaje.
  • raise/2 lanza un error específico por su nombre de módulo, y acepta un argumento de atributos que se utiliza para obtener el error con el mensaje apropiado.

Instrucciones

Mientras continúas tu trabajo en Instruments of Texas, se están logrando avances en la implementación en Elixir de la calculadora RPN. A tu equipo le gustaría poder lanzar errores más específicos que los errores genéricos proporcionados por la biblioteca estándar. Estás investigando un poco, pero has decidido implementar dos nuevos errores que implementan el Comportamiento de excepción.

1. Error de división por cero

Dividir un número por cero produce un resultado indefinido, que el equipo decide que se representa mejor con un error.

Implementa el módulo DivisionByZeroError para que tenga el mensaje de error: "division by zero occurred"

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

2. Error de subdesbordamiento de pila

Las calculadoras RPN usan una pila para llevar un registro de los números antes de que se sumen. El equipo representa esta pila con una lista de números (enteros y de punto flotante), por ejemplo: [3, 4.0]. Cada operación necesita una cantidad específica de números en la pila para poder realizar su cálculo. Cuando no hay suficientes números en la pila, esto se llama error de subdesbordamiento de pila. Implementa la excepción StackUnderflowError que proporciona un mensaje predeterminado y contexto adicional opcional

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

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

3. Escribe una función que divida

Implementa la función divide/1 que toma una pila (una lista de dos números) y:

  • lanza subdesbordamiento de pila cuando la pila no contiene suficientes números
  • lanza división por cero cuando el divisor es 0 (ten en cuenta que la pila de números se almacena en orden inverso)
  • realiza la división cuando no se lanzan errores
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

¡Nota que el orden de la lista está invertido!

Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Elixir Exercism

¿Todo listo para empezar Subdesbordamiento de pila?

Regístrate en Exercism para aprender y dominar Elixir con 58 conceptos168 ejercicios y mentoría humana real, todo gratis.