مسیرها
/
Elixir
Elixir
/
تمرین‌ها
/
ماشین‌حساب RPN
ماشین‌حساب RPN

ماشین‌حساب RPN

تمرین یادگیری

مقدمه

خطاها

خطاها رخ می‌دهند. در Elixir، هرچند اغلب می‌گویند «بگذارید کرش کند»، گاهی لازم است فراخوانی تابع را نجات دهیم و به وضعیت مطلوب شناخته‌شده‌ای برگردانیم تا یک قرارداد نرم‌افزاری برآورده شود. در برخی زبان‌ها، از خطاها به عنوان روشی برای کنترل جریان برنامه استفاده می‌شود، اما در Elixir این الگو توصیه نمی‌شود. اغلب می‌توانیم توابعی را که ممکن است خطا ایجاد کنند، فقط از روی اسمشان تشخیص دهیم: توابعی که خطا ایجاد می‌کنند باید در انتهای اسمشان ! داشته باشند. این در مقابل توابعی است که {:ok, value} یا :error برمی‌گردانند. به این نمونه‌های کتابخانه‌ای نگاه کنید:

Map.fetch(%{a: 1}, :b)
# => :error
Map.fetch!(%{a: 1}, :b)
# => raises KeyError

Try/Rescue

Elixir ساختاری برای نجات از خطاها با استفاده از try .. rescue فراهم می‌کند.

try do
  raise RuntimeError, "error"
rescue
  e in RuntimeError -> :error
end

بیایید این ساختار را بررسی کنیم:

  • خط ۱، بلوک با try اعلام می‌شود.
  • خط ۲، فراخوانی تابعی که ممکن است خطا بدهد اینجا قرار می‌گیرد؛ در این مورد ما raise/2 را فراخوانی می‌کنیم.
  • خط ۴، در بخش rescue، روی اسم ماژول خطای ایجادشده تطابق الگو می‌دهیم
    • در سمت چپ ->:
      • e با ساختار خطا تطبیق داده می‌شود.
      • in یک کلیدواژه است.
      • RuntimeError خطایی است که می‌خواهیم از آن نجات پیدا کنیم.
        • اگر می‌خواستیم از همه‌ی خطاها نجات پیدا کنیم، می‌توانستیم به‌جای اسم ماژول از _ استفاده کنیم یا کلیدواژه‌ی in را کاملاً حذف کنیم.
    • در سمت راست:
      • دستوراتی که در صورت تطبیق خطا اجرا می‌شوند.

ساختارهای خطا

خطاهایی (که گاهی «استثنا» هم نامیده می‌شوند) که به این شکل از آن‌ها نجات پیدا می‌کنید، ساختار هستند. نجات دادن از خطاها در Elixir به‌ندرت انجام می‌شود. معمولاً خطای نجات‌یافته ثبت می‌شود یا به یک سرویس پایش خارجی فرستاده می‌شود و سپس دوباره ایجاد می‌گردد. یعنی معمولاً به ساختار درونی آن خطای مشخص اهمیتی نمی‌دهیم.

در مفهوم Exceptions درباره‌ی ساختارهای خطا بیشتر یاد می‌گیرید، از جمله این‌که چطور خطای سفارشی خودتان را تعریف کنید.

دستورالعمل‌ها

در حین کار در Instruments of Texas، به شما سپرده شده است که روی یک ماشین‌حساب آزمایشی با نمادگذاری لهستانی معکوس [RPN] کار کنید که با Elixir نوشته شده است. تیم شما با مشکلی روبه‌روست: بعضی از عملیات‌ها خطا می‌دهند و فرایند را از کار می‌اندازند. به شما سپرده شده است تابعی بنویسید که دور تابع عملیات را می‌گیرد تا بتوان خطاها را با کد اصطلاحی Elixir به شکلی شایسته‌تر مدیریت کرد.

1. به تیم هشدار دهید

تابع calculate!/2 را طوری پیاده‌سازی کنید که تابع عملیات را با پشته به عنوان تنها آرگومان فراخوانی کند. تابع عملیات جای دیگری تعریف شده است، اما می‌دانید که یا با موفقیت به پایان می‌رسد یا خطا ایجاد می‌کند.

stack = []
operation = fn _ -> :ok end
RPNCalculator.calculate!(stack, operation)
# => :ok

stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate!(stack, operation)
# => ** (ArgumentError) An error occurred

اسم توابعی که به ! ختم می‌شوند، هشداری برای برنامه‌نویسان است که این تابع ممکن است خطا ایجاد کند

2. خطا را مهار کنید

وقتی بیشتر تحقیق می‌کنید، متوجه می‌شوید که بسیاری از توابع از اتم‌ها و تاپل‌ها برای نشان دادن موفقیت یا شکست خود استفاده می‌کنند. calculate/2 را با همین راهکار پیاده‌سازی کنید.

stack = []
operation = fn _ -> "operation completed" end
RPNCalculator.calculate(stack, operation)
# => {:ok, "operation completed"}

stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate(stack, operation)
# => :error

3. پیام را منتقل کنید

بعضی از خطاها حاوی اطلاعات مهمی هستند که همکارانتان برای تضمین کارکرد درست سیستم به آن‌ها نیاز دارند. calculate_verbose/2 را پیاده‌سازی کنید تا پیام خطا را منتقل کند. خطا یک ساختار است که فیلد :message را دارد.

stack = []
operation = fn _ -> "operation completed" end
RPNCalculator.calculate_verbose(stack, operation)
# => {:ok, "operation completed"}

stack = []
operation = fn _ -> raise ArgumentError, "An error occurred" end
RPNCalculator.calculate_verbose(stack, operation)
# => {:error, "An error occurred"}
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Elixir Exercism

آماده‌اید ماشین‌حساب RPN را شروع کنید؟

در Exercism ثبت‌نام کنید تا Elixir را همراه با 58 مفهوم168 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.