Az Elixirben minden hiba az Exception viselkedést valósítja meg. Ahogy az Access viselkedés, úgy az Exception viselkedés is visszahívó függvényeket definiál, amelyeket egy modulnak meg kell valósítania, hogy teljesítse a viselkedés szoftverszerződését. Miután egy hiba definiálva van, a következő tulajdonságokkal rendelkezik:
:message mezője.raise/1 és raise/2 segítségével használható a kívánt hiba dobásáraAz Exception viselkedés emellett két visszahívó függvényt is meghatároz: a message/1-et és az exception/1-et. Ha nem valósítod meg őket, a rendszer az alapértelmezett megvalósításokat használja. A message/1 a raise hívásakor a hibastruktúrát olvasható üzenetté alakítja. Az exception/1 lehetővé teszi, hogy a raise/2 hívásakor további kontextust adj az üzenethez
Ahhoz, hogy egy hibamodulból kivételt definiáljunk, a defexception makrót használjuk:
# 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
A definiált hibák ugyanúgy használhatók, mint a beépített hibák, akár a raise/1, akár a raise/2 segítségével.
raise/1 a modul nevével dob egy adott hibát, vagy ha az argumentum egy string, akkor egy RuntimeError-t dob, amelynek az üzenete maga a string.raise/2 a modul nevével dob egy adott hibát, és elfogad egy attribútumokat tartalmazó argumentumot, amelynek segítségével a megfelelő üzenetű hiba áll elő.Miközben tovább dolgozol az Instruments of Texas-nál, szépen halad az RPN-számológép Elixir-implementációja. A csapatod olyan hibákat szeretne dobni, amelyek konkrétabbak, mint a standard könyvtár által biztosított általános hibák. Épp kutatást végzel, de úgy döntöttetek, hogy létrehoztok két új hibát, amelyek megvalósítják az Exception Behaviour-t.
Egy szám nullával való osztása definiálatlan eredményt ad, amit a csapat szerint a legjobban egy hiba fejez ki.
Úgy valósítsd meg a DivisionByZeroError modult, hogy a hibaüzenete a következő legyen: "division by zero occurred"
raise DivisionByZeroError
# => ** (DivisionByZeroError) division by zero occurred
Az RPN-számológépek vermet használnak, hogy nyilvántartsák a számokat, mielőtt összeadnák őket. A csapat ezt a vermet számok listájaként ábrázolja (egészek és lebegőpontos számok), például: [3, 4.0]. Minden művelethez adott mennyiségű számnak kell lennie a vermen, hogy elvégezhesse a számítást. Amikor nincs elég szám a vermen, azt verem alulcsordulásnak nevezzük. Valósítsd meg a StackUnderflowError kivételt, amely alapértelmezett üzenetet és opcionális kiegészítő kontextust biztosít
raise StackUnderflowError
# => ** (StackUnderflowError) stack underflow occurred
raise StackUnderflowError, "when dividing"
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing
Valósítsd meg a divide/1 függvényt, amely egy vermet (két szám listáját) kap, és:
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
Figyelj, a lista sorrendje fordított!
Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Elixir nyelvet 58 fogalom168 feladat segítségével, valódi emberi mentorálással, mindez ingyen.