Όλα τα σφάλματα στην Elixir υλοποιούν τη Συμπεριφορά Exception. Ακριβώς όπως η Συμπεριφορά Access, η Συμπεριφορά Exception ορίζει συναρτήσεις callback που πρέπει να υλοποιήσει ένα module για να εκπληρώσει το συμβόλαιο λογισμικού της συμπεριφοράς. Μόλις οριστεί ένα σφάλμα, έχει τις εξής ιδιότητες:
:message.raise/1 και raise/2 για να πετάξει το σφάλμα που θέλειςΗ Συμπεριφορά Exception ορίζει επίσης δύο callbacks: τις message/1 και exception/1. Αν δεν υλοποιηθούν, θα χρησιμοποιηθούν προεπιλεγμένες υλοποιήσεις. Η message/1 μετατρέπει το struct σφάλματος σε ένα αναγνώσιμο μήνυμα όταν κληθεί με το raise. Η exception/1 επιτρέπει να προστεθεί επιπλέον περιβάλλον στο μήνυμα όταν κληθεί με το raise/2
Για να ορίσουμε μια εξαίρεση από ένα module σφάλματος, χρησιμοποιούμε το 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
Τα σφάλματα που έχουν οριστεί μπορούν να χρησιμοποιηθούν όπως ένα ενσωματωμένο σφάλμα, είτε με το raise/1 είτε με το raise/2.
raise/1 πετάει ένα συγκεκριμένο σφάλμα με βάση το όνομα του module του ή, αν το όρισμα είναι συμβολοσειρά, πετάει ένα RuntimeError με τη συμβολοσειρά ως μήνυμα.raise/2 πετάει ένα συγκεκριμένο σφάλμα με βάση το όνομα του module του και δέχεται ένα όρισμα attributes, το οποίο χρησιμοποιείται για να ληφθεί το σφάλμα με το κατάλληλο μήνυμα.Καθώς συνεχίζεις τη δουλειά σου στην Instruments of Texas, γίνεται πρόοδος στην υλοποίηση σε Elixir της αριθμομηχανής RPN. Η ομάδα σου θα ήθελε να μπορεί να πετάει σφάλματα πιο συγκεκριμένα από τα γενικά σφάλματα που παρέχει η βασική βιβλιοθήκη. Κάνεις κάποια έρευνα, αλλά έχεις αποφασίσει να υλοποιήσεις δύο νέα σφάλματα που υλοποιούν το Exception Behaviour.
Η διαίρεση ενός αριθμού με το μηδέν παράγει ένα απροσδιόριστο αποτέλεσμα, το οποίο η ομάδα αποφασίζει ότι αναπαρίσταται καλύτερα με ένα σφάλμα.
Υλοποίησε το άρθρωμα DivisionByZeroError ώστε να έχει το μήνυμα σφάλματος: "division by zero occurred"
raise DivisionByZeroError
# => ** (DivisionByZeroError) division by zero occurred
Οι αριθμομηχανές RPN χρησιμοποιούν μια στοίβα για να κρατούν τους αριθμούς πριν γίνει πάνω τους κάποια πράξη. Η ομάδα αναπαριστά αυτή τη στοίβα με μια λίστα αριθμών (ακέραιων και κινητής υποδιαστολής), π.χ.: [3, 4.0]. Κάθε πράξη χρειάζεται έναν συγκεκριμένο αριθμό αριθμών στη στοίβα για να εκτελέσει τον υπολογισμό της. Όταν δεν υπάρχουν αρκετοί αριθμοί στη στοίβα, αυτό ονομάζεται σφάλμα υποχείλισης στοίβας. Υλοποίησε την εξαίρεση StackUnderflowError που παρέχει ένα προεπιλεγμένο μήνυμα και προαιρετικό επιπλέον πλαίσιο
raise StackUnderflowError
# => ** (StackUnderflowError) stack underflow occurred
raise StackUnderflowError, "when dividing"
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing
Υλοποίησε τη συνάρτηση divide/1 που παίρνει μια στοίβα (μια λίστα με δύο αριθμούς) και:
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
Πρόσεξε ότι η σειρά της λίστας είναι αντεστραμμένη!
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Elixir με 58 έννοιες168 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.