להחזיר או לזרוק

27/11/2024

שפות רבות מאפשרות לנו לבחור אם להחזיר ערך שמסמן שגיאה או לזרוק את השגיאה כשדברים לא קורים כמו שתכננו. כך בפייתון אני יכול להוציא ערך ממפה עם הפונקציה get, ואז אם המפתח לא קיים אני מקבל None:

>>> d = {"a": 10, "b": 20}
>>> d.get("a")
10
>>> d.get("d")

או עם אופרטור סוגריים מרובעים שזורק שגיאה אם הערך לא קיים:

>>> d['a']
10
>>> d['d']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'd'

בסקאלה הפונקציה get מחזירה ערך ממפה ואם הוא לא קיים מחזירה None:

scala> Map("a" -> 10, "b" -> 20).get("a")
val res1: Option[Int] = Some(10)

scala> Map("a" -> 10, "b" -> 20).get("d")
val res3: Option[Int] = None

ואפשר גם להפעיל את המפה כמו פונקציה על המפתח בשביל לשלוף ערך או לזרוק שגיאה אם המפתח לא קיים:

scala> Map("a" -> 10, "b" -> 20)("a")
val res2: Int = 10

scala> Map("a" -> 10, "b" -> 20)("d")
java.util.NoSuchElementException: key not found: d
  at scala.collection.immutable.Map$Map2.apply(Map.scala:316)
  ... 30 elided

הרבה זמן חשבתי שכדאי להשתמש בפונקציות אלה לפי ההקשר. כשצריך לזרוק שגיאה אני אבחר את הסוג שזורק שגיאות, וכשצריך להחזיר ערך שגיאה אני אשתמש בפונקציות מהסוג שמחזיר ערכים.

שמתי לב שלאורך זמן אני מתחיל לבנות מנגנונים סביב שיטת העבודה שבחרתי, פונקציות שקוראות לפונקציות והרגלים איך לדבג כל בעיה, וככל שהמערכת גדלה ערבוב שני הסוגים באותו פרויקט גורר כתיבה של קוד כפול מסביב. לאחרונה אני מנסה להתרגל להשתמש תמיד באותו סט של פונקציות וחייב להודות שזה בינתיים מוכיח את עצמו.

ומה אתכם? איזה משתי השיטות אתם מעדיפים? ומה לגבי ערבוב השיטות באותו פרויקט?