هر کامنتی که با کد همگام نگه داشته نشود دیر یا زود دروغ میگوید، و هیچ ابزاری این را گزارش نمیکند. تنها استثنا مستندی است که خودش اجرا میشود.
سه نمونه داخل رشته مستندات تابع کرایه، درست به همان شکلی که در مفسر تعاملی تایپ میشوند:
>>> kerayeh_qalam(12)
54000>>> kerayeh_qalam(8, shekastani=True)
50400.0>>> kerayeh_qalam(0)
0
اجرای python3 -m doctest kerayeh.py هر سه را میگیرد و اگر همه درست باشند هیچ چیزی چاپ نمیکند. حالا نرخ پایه را از چهار هزار و پانصد به چهار هزار و هشتصد عوض کنید و همان دستور میگوید:
Failed example: kerayeh_qalam(12)Expected: 54000Got: 57600
این تفاوت اصلی است. یک کامنت نمیتواند به شکلی غلط شود که چیزی متوجهش شود؛ یک نمونه اجراشدنی میتواند و همان لحظه هم میشود.
کامنت چه چیزی باید بگوید
کامنتی که میگوید کد چه میکند تکرار است و اولین چیزی است که کهنه میشود. کامنتی که میگوید چرا اینطور نوشته شده تکرار نیست و هیچجای دیگری هم نوشته نمیشود. سه چیز واقعا ارزش کامنت دارند: تصمیمی که گزینه بدیهیتری داشت و رد شد، ارجاع به یک قاعده بیرونی مثل شماره یک بخشنامه یا یک محدودیت سرویس، و راهحل موقتی با شرطی که میگوید کی برداشته شود.
اگر کامنت دارد نامها را توضیح میدهد، مسئله نامهاست: ارزانترین مستندی که وجود دارد. و اگر دارد ساختار یک تابع طولانی را توضیح میدهد، آن کامنتها معمولا فهرست نام تابعهایی هستند که هنوز استخراج نشدهاند: عوض کردن شکل، بدون عوض کردن رفتار.
مستند در سه سطح، و مخاطب هرکدام
رشته مستندات یک تابع برای کسی است که همین حالا میخواهد صدایش بزند و کافی است بگوید چه میگیرد، چه برمیگرداند، و در چه حالتی خطا میدهد. فایل راهنمای مخزن برای کسی است که تازه رسیده و باید در ده دقیقه پروژه را روی ماشین خودش بالا بیاورد. و ثبت تصمیمهای معماری برای کسی است که شش ماه بعد میپرسد چرا اینطور شد؛ اگر جایی برای آن نباشد، جواب در فایلهای چت گم میشود و عملا وجود ندارد.
جایی که کار گیر میکند، فارسی و لاتین در یک فایل است
در کد ایرانی خیلی وقتها کامنتها فارسیاند و کد لاتین، و همین ترکیب دو مشکل واقعی دارد. اول اینکه در بسیاری از ترمینالها و در بعضی ابزارهای تفاوتگیری، متن فارسی و لاتین در یک سطر جابهجا نمایش داده میشوند و خواندن تفاوت را سخت میکنند. دوم اینکه نمونههای داخل رشته مستندات باید دقیقا با خروجی واقعی مطابق باشند، پس اگر تابع رشته فارسی برمیگرداند، نمونه هم باید همان رشته را با همان نویسهها داشته باشد؛ یک فاصله مجازی جاافتاده، آزمون را میشکند بیآنکه تفاوت به چشم بیاید. راه عملی این است که کامنتهای توضیحی فارسی باشند و نمونههای اجراشدنی همیشه روی عدد و داده لاتین کار کنند.
ابزار، و سالی که این حرف درست است
در سال ۲۰۲۶ ماژول doctest در کتابخانه استاندارد و رایگان است و جای نمونهای را گرفته که در مستندات نوشته میشود و هیچوقت اجرا نمیشود؛ اجرایش هیچ وابستگیای ندارد و در خط لوله هم یک دستور است. برای مستند کردن یک پروژه کامل، mkdocs از همان فایلهای متنی مخزن سایت میسازد و متنباز است، اما نصبش از مخزن بستهها انجام میشود. اگر فقط یک چیز از این صفحه برمیدارید، همان دستور doctest باشد.
پرسش بعدی این است که وقتی نمونهها از چند سطر بیشتر شدند و حالتهای مرزی هم لازم شدند، کجا باید بروند، که یک چیز در هر بار، سریع و جدا جوابش است. و جایی که کامنتها اولین بار خوانده و دربارهشان بحث میشود دنبال چه بگردید، و چطور بگویید است.