دیباگ چیست؟ – توضیح اهمیت در برنامه نویسی + شرح فرآیند
در این مطلب از دیدگاه برنامه نویسی پیرامون اینکه دیباگ چیست بحث شده است و همچنین شرح داده میشود که چگونه دیباگ کنیم و چطور میتوان در دیباگ کردن (Debug کردن) پیشرفت داشت و این مهارت را در خود بهبود داد.
دیباگ چیست و Debug کردن چطور شکل گرفت؟
دو کلمه و اصطلاح «باگ» (Bug) و «دیباگ کردن» (Debugging) در حوزه نرمافزار عموماً به دریاسالار «گریس هاپر» (Grace Hopper) نسبت داده میشوند. خانم هاپر یکی از اسطورههای نامآور در حوزه علوم کامپیوتر و برنامه نویسی به حساب میآید. او کدنویسی و ایجاد اولین کامپایلر جهان را انجام داده است.
در سال ۱۹۴۰، زمانی که دریاسالار هاپر در حال کار روی توسعه و ساخت کامپیوتری برای نیروی دریایی آمریکا در دانشگاه هاروارد بود، دستیاران او شاپرک (بید | یعنی یک حشره واقعی) را پیدا کردند که در داخل رلهای گیر کرده و باعث شده بود کامپیوتر از کار بیفتد.
وقتی آنها در حال رفع مشکل بودند، خانم هاپر گفت، آنها دارند سیستم را «دیباگ» میکنند. «دیباگ کردن» (Debugging) را در لغت میتوان «حشرهزدایی» ترجمه کرد و مفهوم آن در علوم کامپیوتر و برنامه نویسی «خطایابی»، «رفع عیب» یا «اشکالزدایی» است.
برای علاقهمندان به حوزه «ریشهشناسی» (Etymology) که شاخهای از علم زبانشناسی به حساب میآید، ممکن است دانستن این موضوع جالب باشد که کلمه دیباگ کردن یا همان Debugging قبل از ورود به دنیای برنامه نویسی و علوم کامپیوتر به عنوان اصطلاحی در هوانوردی به کار گرفته میشد.
همچنین ظاهراً به نوعی اثبات شده است که توماس ادیسون هم از این اصطلاح به معنای «خطای فنی» در سال ۱۸۷۸ میلادی (۱۲۵۷ خورشیدی) استفاده کرده است.
خوشبختانه امروزه مواردی که لازم باشد واقعاً حشرهای را از داخل یک کامپیوتر بیرون بیاوریم خیلی به ندرت اتفاق میافتند. بنابراین، هدف اصلی این مقاله، پاسخ به سوال دیباگ چیست از منظر توسعه نرم افزار و برنامه نویسی است. دیباگ کردن بخشی کلیدی و اساسی در برنامه نویسی و چرخه توسعه نرم افزار به حساب میآید و این اهمیت همواره پا بر جا خواهد بود.
دیباگ به انگلیسی
دیباگ به انگلیسی به صورت «Debug» نوشته میشود. پیشوند De به کلمه Bug اضافه شده است که به معنی زدایش است. در واقع کلمه Debug از ۲ بخش De و Bug تشکیل شده است. کلمه Bug در لغت یعنی حشره، اما در دنیای کامپیوتر برای اشاره به خطا یا ایراد در کدها به کار میرود. بنابراین دیباگ به انگلیسی در لغت یعنی حشرهزدایی و در دنیای برنامه نویسی به معنی اشکالزدایی یا خطایابی است. پیش از آنکه بتوانیم دقیقاً درک کنیم که دیباگ چیست باید ابتدا به این مسئله بپردازیم که اهمیت یادگیری دیباگ چیست و چرا باید Debug کردن را بیاموزیم.
چرا باید Debug کردن را یاد بگیریم ؟
باگها و خطاها در توسعه نرم افزار بسیار مستعد رخ دادن هستند، زیرا توسعه نرم افزار و برنامه نویسی فعالیتی بسیار مفهومی و انتزاعی (غیر قابل لمس و ذهنی یا تخیلی) به حساب میآید. برنامهنویسان و توسعهدهندگان با دادهها و اطلاعات سر و کار دارند. آنها دادهها را سازماندهی میکنند، انتقال میدهند، بهروزرسانیهای لازم را انجام میدهند، اطلاعات را ویرایش میکنند یا ممکن است آنها را به جایی بفرستند و دوباره آنها را دریافت کنند.
برنامهنویسان تمام مدت با دادهها کار میکنند، اما این تعامل به طور مستقیم انجام نمیشود. در واقع اطلاعات به صورت فیزیکی در کامپیوتر ذخیره نمیشوند، حداقل قالب و فرمت آنها به آن شکلی نیست که کاربران تصور میکنند. عملکرد داخلی کامپیوترها تنها به صورت پالسهای الکتریکی است که سپس در سطحی انتزاعی به اعداد صفر و یک تبدیل میشوند و در سطوح انتزاع بالاتر، این صفر و یکها به صورت هر نوعی از اطلاعاتی نمود پیدا میکنند که با آنها سر و کار داریم.
برای تعامل با کامپیوترها و استفاده از آنها از زبانهای برنامه نویسی استفاده میشود. در زبانهای برنامه نویسی، سطوحی از انتزاع برای وظایف عملیاتی فراهم میشود تا بتوان برای کامپیوترها مشخص کرد که چه کاری را انجام دهند. همچنین این لایههای انتزاعی برای دادهها و اطلاعات تحت مدیریت در برنامه نویسی هم اعمال میشوند.
باید به این نکته توجه داشت که برنامه نویسی همواره فعالیتی بسیار انتزاعی بوده و به راحتی ممکن است آنچه کامپیوتر واقعاً انجام میدهد در معرض دید برنامهنویس نباشد، یا معمولاً نمیتوان مشخص کرد که در یک خط کد مشخص، کامپیوتر دقیقاً در حال کار روی چه اطلاعاتی است. بنابراین، دادن دستور اشتباه به کامپیوتر و نرسیدن به هدفی که به دنبال آن هستیم به سادگی میتواند اتفاق بیفتد.
یکی از لطیفههایی که در این خصوص بین برنامهنویسان نقل میشود این است که معمولاً یک برنامهنویس ۵ دقیقه برای نوشتن کدها زمان صرف میکند و ۵ ساعت سعی میکند بفهمد چرا برنامه مطابق انتظار عمل نمیکند.
فارق از اینکه چقدر در برنامهنویسی مهارت داشته باشیم، ساعتهای بیشماری برای دیباگ کردن کدها مورد نیاز است، بنابراین باید این مهارت را تا حد امکان در خودمان تقویت کنیم و سرعت عمل خود را تا جایی که میتوانیم افزایش دهیم.
دیباگ چیست و Debug کردن چگونه انجام می شود ؟
دیباگ کردن را میتوان فرایند یافتن ریشه یک مشکل در کدهای منبع و رفع آن در نظر گرفت. معمولاً این فرایند با تفکر در مورد همه علتهای ممکن برای بروز این مشکل آغاز میشود، سپس هر یک از این فرضیهها (با شروع از محتملترین آنها) ارزیابی و بررسی میشوند تا وقتی که در نهایت ریشه اصلی بروز مشکل را پیدا میکنیم. سپس باید اصلاحات لازم را انجام داد و اطمینان حاصل کرد که دیگر این ایراد رخ نخواهد داد. هیچ راهحل و راهکار جادویی برای دیباگ کردن و رفع باگها وجود ندارد. معمولاً برای Debug کردن لازم است ترکیبی از تمهیدات مختلف انجام شوند. این تمهیدات در ادامه فهرست شدهاند:
- جستجو در گوگل
- ثبت وقایع کدها (لاگ کردن | Logging)
- بررسی منطق برنامه در مقایسه با آنچه واقعاً در حال وقوع است.
بنابراین بهتر است در ادامه مطلب دیباگ چیست ابتدا به «چارچوب فکری دیباگ کردن» پرداخته شود و سپس برخی از ابزارهایی را معرفی کنیم که میتوان برای Debug کردن کدها از آنها استفاده کرد.
اکنون تا حد زیادی متوجه شدیم دیباگ چیست و بنابراین حالا فرصت مناسبی است تا به این مسئله بپردازیم که برای یادگیری دیباگ کردن چه مهارتهایی را باید بیاموزیم.
چگونه طرز تفکر Debug کردن را در خود تقویت کنیم؟
در این بخش به ارائه ترفندهایی برای قرار گرفتن در چارچوب فکری دیباگ کردن پرداخته شده است و به نوعی فرایند Debug کردن شرح داده میشود. ابتدا فهرستی از این ترفندها ارائه شده است و سپس هر یک از آنها به طور جداگانه شرح داده میشوند.
- توجه به پیامهای خطا
- گوگل کردن آنچه نمیدانیم
- شرح منطق کدها به خودمان، شخصی دیگر یا به هر جسم و شی در دسترس
- کاهش دادن یا محدود کردن ناحیه وقوع مشکل و درک اینکه خطا دقیقاً در کجا اتفاق افتاده است.
- در نظر گرفتن زنگ تفریح برای خود و تفکر راجع به چیزهای دیگر
- کمک گرفتن از دیگران
- حصول اطمینان نسبت به از بین رفتن کامل باگ
- رعایت اصول کدنویسی واضح (تمیز)
- رعایت اصول DRY
- نوشتن کدهای تا حد امکان ساده
- استفاده از اصول SOLID
تقویت خط فکری Debug کردن با توجه بیشتر به پیام های خطا
تقریباً در هر محیط توسعه یا کد ادیتوری اگر کدها به درستی اجرا نشوند، به احتمال زیاد پیغام خطایی به برنامهنویس نشان داده خواهد شد. این پیامهای خطا (تا حدودی) توضیح میدهند که چرا کدها به درستی کار نمیکنند. مثلاً کدهای زیر را در نظر بگیرید:
1mickTheBug('Im a scary bug!')
2
3const mickTheBug = message => console.log(message)
با اجرای کدهای بالا، خطای زیر نمایش داده میشود:
ReferenceError: Cannot access 'mickTheBug' before initialization at Object.<anonymous> (/home/German/Desktop/ger/code/projects/test.js:4:1)
پیام خطای بالا به وضوح به مشکل اشاره میکند و حتی در آن مشخص شده است که خطا در کدام خط از برنامه اتفاق افتاده است (test.js:4:1 ). ممکن است خواندن پیغامهای خطا توصیهای بدیهی به نظر برسد، اما بسیار متعجب خواهید شد اگر بشنوید چه تعدادی از برنامهنویسان پیغامهای خطا را با دقت نمیخوانند و تنها با اولین ایدهای که به ذهنشان میرسد با باگ برخورد میکنند.
وجود پیامهای خطا بیدلیل نیست و هدف از نمایش آنها این است که حداقل ایده اولیهای راجع به این موضوع بدست آوریم که خطا در کدام قسمت برنامه و به چه دلیلی رخ داده است.
منظور از گوگل کردن و جستجو برای یافتن راه حل در دیباگ چیست ؟
اگر پیغام خطایی که دریافت شده برای برنامهنویس واضح نباشد یا نتوان فهمید که چرا چنین پیام خطایی دریافت شده، اولین گام مناسبی که میتوان در این شرایط برداشت، گوگل کردن پیغام خطا است.
یکی از شگفتانگیزترین حقایق راجع به کدنویسی، گستردگی و وسعت زیاد اجتماع آنلاین برنامهنویسان است. تقریباً به طور قطع میتوان گفت که تعداد زیادی از برنامهنویسان پیش از این با همان پیام خطا مواجه شدهاند و آن را حل کردهاند و در اینترنت روش رفع آن را به دیگران توضیح دادهاند تا سایر افراد ناچار نشوند دوباره با آن باگ دست و پنجه نرم کنند.
برای گوگل کردن باگ چه ترفندهایی وجود دارند؟
در زمان گوگل کردن، بهتر است تا حد امکان جزئیات زیادی را در جستجوی خود به کار بگیریم. مثلاً برای مثال قبلی که بالاتر ارائه شد، میتوانیم عبارت زیر را در گوگل جستجو کنیم:
javascript ReferenceError: Cannot access before initialization
تجربه نشان داده است که استفاده از فناوری مورد استفاده در متن جستجو، نتایج دقیقتری را در پی خواهد داشت. همچنین حذف مواردی که فقط به کدهای خودمان مربوط میشوند و متنهایی نیستند که عمومی باشند و سایرین هم آنها را در خطای مربوطه دریافت کنند (مثلاً نام تابعmickTheBug که خودمان نوشتهایم)، میتواند به دریافت نتیجه بهتر کمک کند.
یک ترفند کاربردی دیگر این است که از منابع قابل اعتماد و جدیدتر استفاده کنیم. قابل اعتماد یعنی مثلاً سند مربوطه رسمی باشد یا راهکار ارائه شده قبلاً توسط دیگران آزمایش شده و به نتیجه رسیده باشد. اهمیت جدید بودن نتایج جستجو هم به این معنی است که راهکارهای مورد استفاده تا حد امکان اخیراً پیادهسازی و اجرا شده باشند. زیرا آنچه که ۵ سال پیش کار میکرده است به احتمال زیاد اکنون بهترین راه ممکن برای دیباگ کردن نخواهد بود.
چرا بررسی مستندات رسمی زبان برنامه نویسی یا فناوری مربوطه برای دیباگ کردن اهمیت دارد؟
چه زمانی که با مبحث جدیدی سرو کار داریم و چه وقتی با یک باگ مواجه شدهایم، مستندات رسمی همیشه باید اولین چیزی باشند که بررسی میکنیم. معمولاً مستندات رسمی کاملترین و بهروزترین منابع اطلاعاتی برای هر ابزار در دسترس به حساب میآیند. اینکه بخواهیم در میان حجم زیادی از اطلاعات فنی به دنبال پاسخ بگردیم، گاهی ممکن است ملالآور یا کلافه کننده باشد، اما در بلند مدت باعث صرفهجویی در زمان خواهد شد.
نکته مهم در خصوص مستندات رسمی این است که گاهی این مستندات حاوی اطلاعات بسیار زیادی هستند و به حدی در آنها به جزئیات پرداخته شده است که بیش از آنکه مفید و کمککننده باشد، گیجکننده هستند. به همین دلیل، به نظر میرسد بهتر باشد همیشه بیش از یک منبع را برای هر موضوع به کار ببریم و در واقع نظرات مختلف را جویا شویم. اگر در منابع مختلف به راهکار مشابهی اشاره شده باشد، این یعنی راهحل مربوطه معتبر است. معمولاً برای یادگیری یک مفهوم جدید یا دیباگ کردن مشکلی در برنامه، درک مطلوب زمانی حاصل میشود که بخشهایی مرتبط در مستندات را بخوانیم، چند مطلب و مقاله مرتبط را مطالعه کنیم و چند ویدیوی آموزشی هم ببینیم.
در ادامه مطلب دیباگ چیست به اهمیت توضیح دادن کدها و منطق آنها با صدای بلاند پرداخته شده است، اما پیش از مجموعه دورههای آموزش برنامه نویسی فرادرس را به علاقهمندان معرفی کردهایم.
معرفی فیلم های آموزش برنامه نویسی
در پلتفرم فرادرس دورههای آموزشی مرتبط با هم به صورت یکجا گردآوری و در قالب مجموعههای آموزشی مختلف دستهبندی شدهاند. یکی از بزرگترین مجموعهها در فرادرس، مجموعه آموزشهای برنامه نویسی است که تعداد زیادی از دورههای مختلف برنامه نویسی در آن جای گرفتهاند. برای یادگیری اکثر زبانهای برنامه نویسی رایج و محبوب، دورههای مختلفی در سطوح مقدماتی، تکمیلی و پیشرفته در دسترس هستند. همچنین تعداد زیادی دوره پروژهمحور نیز برای کاربردها و حوزههای مختلف برنامه نویسی در این مجموعه قابل دسترسی است. در تصویر بالا تنها ۶ دوره مرتبط با این مطلب به عنوان نمونه نمایش داده شده است.
- برای دسترسی به همه دورهها و مشاهده فیلم های آموزش برنامه نویسی فرادرس + اینجا کلیک کنید.
توضیح دادن منطق کدهای خود با صدای بلند
پیشتر به این نکته اشاره شد که برنامه نویسی فعالیتی مفهومی و انتزاعی است و این باعث میشود برخی موارد از دیدرس پنهان بمانند، فرضیههای اشتباهی پرورش داده شوند و نتوان تفسیر درستی نسبت به اطلاعاتی داشت که با آنها سر و کار داریم. یک راهکار خوب برای چیره شدن بر چنین چالشهایی این است که کدهای خود را خط به خط بررسی کنیم، آنها را بخوانیم و با صدای بلند به خودمان توضیح بدهیم. «روش اردک پلاستیکی» (Rubber Duck Technique) راهکار محبوبی برای انجام این کار است.
در اینجا ایده اصلی این است که فرد به جای اینکه فرض کند همه چیز را راجع به کدها میداند، خودش را واقعاً ملزم به خواندن کدها کند. به این روش میتوان منطق شکل گرفته را در ذهن خود با آنچه مقایسه کرد که واقعاً در حال رخ دادن است. این حقیقت که انسان تمایل دارد فرضیههایی را در زهن خود بپروراند و به جزئیات به صورت موشکافانه توجه نکند، پدیدهای است که جزئی از طبیعت انسان به حساب میآید. در واقع این رفتار غریزی، ساز و کاری است که به انسان کمک میکند انرژی خود را ذخیره سازد و کارها را سریعتر انجام دهد. اما در زمان Debug کردن لازم است ذهن خود را به همراهی وادار و تا حد امکان تمرکز خود را به جزئیات معطوف کنیم.
کوچک تر کردن مشکل برای یافتن محل وقوع باگ
با بزرگتر شدن کدهای منبع برنامه، تحلیل خط به خط کدها برای دیباگ کردن بسیار دشوار خواهد شد. بنابراین، استفاده از روش تقسیم و غلبه ایده مناسبی به نظر میرسد. میتوان کاوش را از قسمتهایی شروع کرد که احتمال وقوع مشکل در آنها بیشتر است. برای درک بهتر این موضوع، بهتر است مثالی ارائه شود.
مثال کوچک تر کردن مشکل برای یافتن محل وقوع باگ
برای مثال، تابعی داریم که عددی را دریافت میکند و حاصلضرب آن در ۲ را بازمیگرداند و تابع دیگری هم وجود دارد که نام، نام خانوادگی و نتیجه تابع ضربکننده را چاپ میکند.
1const multiply = num => num*2
2
3const mickTheBug = async (firstName, lastName, age) => {
4 console.log(`My name is ${firstName} ${lastName} and the double of my age is ${multiply(age)}`)
5}
6
7mickTheBug('Mick', 10)
کدها قابل درک هستند و بدون بروز هیچگونه خطایی اجرا میشوند، اما خروجی کدهای بالا به صورت زیر خواهد بود:
My name is Mick 10 and the double of my age is NaN
خروجی بالا از لحاظ مفهومی اشتباه است و مطابق انتظار نیست. اینجا میتوان مشاهده کرد که10 در جایی چاپ شده است که در واقعlastName باید آنجا چاپ ميشد. ملاحظه میشود که پارامترها در همان خطی تنظیم میشوند که تابع فراخوانی شده است. احتمالاً روش مناسب برای شروع این است که بررسی کنیم آیا پارامترها به شکل صحیحی ارجاع داده شدهاند یا خیر. در اینجا ملاحظه میشود که ۲ پارامتر Mick و 10 ارجاع داده شده است، اما تابع انتظار دریافت ۳ پارامترlastName ،firstName و age را دارد.
- نکته: البته در برخی از زبانهای برنامه نویسی جدیدتر، مثل TypeScript از انجام این اشتباه جلوگیری میشود.
ممکن است این مثال بسیار ساده و ابتدایی به نظر برسد، اما در هر صورت نشان میدهد که چگونه میتوانیم حتی در صورتی که هیچ پیغام خطایی وجود نداشته باشد، استنباط کنیم مشکل از کجا نشأت میگیرد. در چنین مواقعی باید سعی کنیم سوالاتی مشابه موارد زیر را از خودمان بپرسیم:
- چطور بفهمم باگ وجود دارد؟
- چه ورودی را دارم فراهم میکنم؟ این ورودی از کجا میآید؟ آیا این ورودی با آنچه تابع انتظار دارد یکسان است؟
- چه خروجی دریافت میشود؟ در خروجی چه تغییری نسبت به ورودی ایجاد شده است؟
- آیا موجودیت دیگری در تعامل با این قطعه کد وجود دارد؟
- آیا اخیراً چیزی را تغییر دادهام که ممکن است باعث عملکرد نادرست کدها شده باشد؟
استراحت کردن و فکر نکردن به باگ
بسیاری از باگها مانند مثالهایی که تا اینجا مشاهده شدند به راحتی قابل رفع و Debug کردن هستند. اما بسیاری از باگهای دیگری هم هستند که به راحتی قابل رفع نخواهند بود و در بسیاری از موارد باید برای ساعتها (روزها) با باگها جنگید تا در نهایت بتوان به راهحل درست رسید.
در چنین مواقعی، بسیار مهم است که به شرایط ذهنی خود توجه کنیم. برنامه نویسی فعالیتی تماماً ذهنی است. بنابراین، چگونگی کارکرد مغز در یک لحظه خاص یا اینکه وضعیت احساسی فرد چگونه باشد، روی نحوه کدنویسی و توانایی فرد در حل مسائل تاثیرگذار است. اگر ساعتها برای خواندن چندین باره کدها با صدای بلند، گوگل کردن و جستجو در پرسشهای مطرح شده در سایت Stack Overflow وقت صرف شود و همچنان در کدها باگ وجود داشته باشد، دیر یا زود کلافه خواهیم شد و فشار بیش از حد روی خود وارد خواهیم کرد.
رفته رفته با امتحان کردن راهحلهای مختلف و شکست دوباره، توجه فرد به جزئیات کاهش میيابد و پرش افکار شروع میشود و ایدههای مختلفی همزمان در ذهن شکل خواهند گرفت. وقتی به چنین نقطهای برسیم، کار هوشمندانه این است که کمی قدم بزنیم یا کلاً کار را تا روز بعد رها کنیم.
اگر در چنین شرایط پراسترس و با وضعیت خستگی ذهنی ادامه بدهیم، به احتمال زیاد به راهحل مناسب نخواهیم رسید. حتی بدتر از آن، ممکن است با تغییر مواردی که در واقع مرتبط نیستند، حتی باگ برنامه از آنچه هست بزرگتر شود. وقتی کار را برای مدتی رها کنیم و به چیزی به غیر از دیباگ کردن برنامهمان بیاندیشیم، مغز در پسزمینه به کار کردن روی مشکل ادامه میدهد و ایدهها را بهگونهای ناخودآگاهانه و خلاقانه به هم متصل خواهد کرد.
در بسیاری از مواقع، این مسئله پیش میآید که در حین انجام کارهای روزمره یا به محض آنکه مثلاً صبح روز بعد دوباره به سراغ مشکل میرویم، ناگهان راهکار تازهای به ذهن خطور میکند. در واقع شرایطی پیش میآید که گویی راهحل مشکل درست در برابر دیدگان ما بوده است، اما نمیتوانستیم آن را ببینیم. داشتن تمرکز، خوب استراحت کردن و آرامش خاطر برای نوشتن کدهای باکیفیت و دیباگ کردن به شیوه موثر بسیار مهم است. مرز میان سختکوشی و فرسودهسازی ذهن بسیار باریک و نازک است. بنابراین، توجه به این مسئله و استراحت دادن به خودمان در زمان لازم اهمیت زیادی دارد.
معمولاً زمانی که دیگر ایدهای به ذهن نمیرسد یا شروع به از دست دادن تمرکزمان میکنیم و رویکردهای متفاوت بهگونهای نسنجیده و غیر سازمانیافته امتحان میشوند و جواب نمیدهند، زمان مناسبی برای استراحت و توقف کار است.
علاوه بر این، لازم است در پس ذهن خود این تفکر را داشته باشیم که باگها و Debug کردن هم بخشی از فرایند توسعه نرم افزار به حساب میآیند. یعنی وجود باگ در برنامه بدان معنا نیست که برنامه نویس مهارت ندارد و به درد این حرفه نمیخورد. همه برنامه نویسان، حتی بهترینها هم با باگ در برنامههایشان مواجه میشوند. بنابراین جای نگرانی وجود ندارد و باید از دیباگ کردن به عنوان راهی برای یادگیری بیشتر بهره برد.
منظور از کمک گرفتن از دیگران برای دیباگ چیست ؟
اهمیت انجمنهای آنلاین را نباید دست کم گرفت. اینکه بتوان تقریباً در هر زمینهای تنها در چند ثانیه از طریق سایتهای پرسش و پاسخ از دیگران کمک گرفت، بسیار امکان مفید و شگفتانگیزی است. دسترسی داشتن به انجمنهای سطح بالا که میتوان در آنها از افراد دارای تجربه در زمینه ابزارهای مورد استفاده سوال پرسید و کمک گرفت، بسیار بسیار سودمند و کمک کننده است.
این امکان بسته به این مسئله متفاوت است که دقیقاً در چه شاخهای از برنامه نویسی فعالیت داریم و از چه ابزارهایی استفاده میکنیم، اما در کل وبسایتهایی مثل StackOverflow ،FreeCodeCamp و Discord یا دیگر موارد مثل MeetupJs تحول بزرگی را در این زمینه ایجاد کردهاند.
در استفاده از انجمن های آنلاین برنامه نویسی چه نکات مهمی را باید در نظر داشته باشیم؟
وقتی سوالات خود را در این اجتماعات مطرح میکنیم، معمولاً لازم است موارد زیر را در نظر داشته باشیم.
- باید سعی شود تا حد امکان به جزئیات لازم بپردازیم. همیشه درک کدهای نوشته شده توسط دیگران آسان نیست، بنابراین باید تلاش کنیم پروژه و برنامه خود را به خوبی توضیح دهیم. همچنین باید هدف خود و به آنچه میخواهیم برسیم را توصیف کنیم و دقیقاً مشخص کنیم که با چه مشکلی مواجه هستیم.
- لازم است دقیقاً پیام خطای دریافت شده را در سوال خود بگنجانیم.
- کدهای مربوط به بخشی که تصور میشود مشکل از آنجا نشأت میگیرد را نیز باید نمایش داد.
- لازم است به این مسئله هم اشاره شود که تا کنون چه راهکارهایی امتحان شدهاند و چرا این راهکارها به درستی کار نکردهاند.
- باید پیش از مطرح کردن سوال خود، تحقیقات لازم را برای دیباگ کردن انجام دهیم و در سوال خود هم نشان دهیم که قبلاً برای پیدا کردن مشکل جستجوهای لازم را انجام دادهایم.
- بهتر است مستنداتی را در سوال خود معرفی کنیم که برای رفع مشکل و Debug کردن مطالعه کردهایم و به مواردی اشاره کنیم که در آن مستندات برای رفع مشکل استفاده کردهایم.
- بهتر است دسترسی به همه کدهای برنامه را از طریق یک مخزن آنلاین فراهم کنیم.
رعایت نکات بالا باعث میشود که اشخاص دیگر بتوانند مشکل را بهتر درک کنند و به احتمال زیاد ایدههایی را برای دیباگ کردن کدها در اختیارمان قرار بدهند.
چرا باید قبل از پرسیدن سوال خودمان به دنبال راه حل باشیم؟
اگرچه درخواست کمک کردن هیچ اشکالی ندارد، اما به نظر میرسد پیش از پرسیدن سوال و درخواست از شخصی دیگر برای فکر کردن به جای شما، ابتدا باید واضحترین و آسانترین مسیرها را طی کرد. این یعنی کدهای خود را تجزیه و تحلیل کردهایم، در مورد آن باگ جستجوهای لازم را انجام دادهایم، دیگر راهکارها و مستندات را خواندهایم، راهکارهای بسیاری را امتحان کردهایم و با وجود انجام تمام این کارها، هنوز به نتیجه نرسیدهایم. تنها در چنین شرایطی کمک خواستن از دیگران منطقی است. در واقع این مسئله مربوط میشود به اینکه بتوان به طور مستقل یاد گرفت و مشکلات را حل کرد و برای وقت دیگران ارزش قائل شد.
مشارکت دو طرفه در پرسش و پاسخ
اگر شخصی به سوال ما پاسخ داده، اینکه ما هم به پاسخ انها جواب بدهیم بسیار اهمیت دارد. حال پاسخ ما میتواند این باشد که راهحل ارائه شده جواب داده است یا مشکل همچنان پابرجا است و در پاسخ خود باید دلیل دیباگ نشدن را هم توضیح داد.
آیا تنها دیباگ کردن برنامه های خودمان کافی است؟
باید این نکته را به یاد داشت که سوال مطرح شده به احتمال زیاد در وبسایت مربوطه ذخیره خواهد شد و برای دفعه بعد که شخص دیگری در جستجوی همین باگ باشد، به آن مراجعه خواهد کرد. در واقع اینجا ایده اصلی این است که دانش جدید تولید شود و این دانش برای همه در دسترس قرار بگیرد و نه اینکه فقط همین باگ خاص و مشکل ما رفع شود.
همچنین اگر خودمان به هر طریقی موفق به رفع مشکل و Debug کردن برنامه شدیم، بهترین کار این است که خودمان به سوالی که مطرح کردهایم پاسخ بدهیم و راهحل آن را با همگان به اشتراک بگذاریم. در ادامه این نوع طرز تفکر، اگر در این انجمنها از طریق پرسیدن سوال نقش ایفا میکنیم، خوب است که به سوالات دیگران هم پاسخ بدهیم. هر وقت متوجه شدیم که دانش لازم را داریم، اینکه ما هم کمک کنیم کار بسیار نیکویی است.
بی اعتنایی به افراد مغرور و بد اخلاق
اکثر افراد در انجمنهای مختلف برنامه نویسی انسانهایی خوشبرخورد هستند که حاضرند با آغوش باز به دیگران کمک کنند و دانش خود را به اشتراک بگذارند. اما به هر حال درست مثل سایر جنبههای زندگی، هر از گاهی ممکن است با افرادی مواجه شویم که خلق و خوی درستی ندارند، مغرور هستند یا حتی خشونتآمیز و تهاجمی برخورد میکنند.
توصیهای که میتوان در این خصوص ارائه داد این است که حتی اگر این افراد دانش بیشتری نسبت به ما دارند، نباید به آنها اجازه بدهیم در ما ایجاد وحشت کنند. هیچ کس تا کنون همهچیزدان به دنیا نیامده است و اگر تحقیقات لازم انجام شدهاند و روی مشکل به اندازه کافی کار کردهایم، کاملاً حق داریم هر سوالی که میخواهیم بپرسیم. اگر افراد دیگر مغرور و گستاخ هستند، این به شخصیت خودشان مربوط میشود و به ما ارتباطی ندارد.
حصول اطمینان از Debug کردن صحیح و کامل
تنها موردی که حتی نسبت به جدال با باگی سرسخت و مقاوم عذاب بیشتری به همراه دارد این است که دیباگ کردن را انجام بدهیم و بعداً متوجه شویم که باگ همچنان وجود دارد و رفع نشده است؛ یا حتی بدتر از آن، مشخص شود که حتی با Debug کردن اشتباه، باگهای بیشتری هم به وجود آمدهاند.
برای پیشگری از وقوع دیباگ کردن اشتباه، تست، آزمایش و ارزیابی کدها اهمیت زیادی دارد. بسیار بهتر خواهد بود اگر بتوان فرایند تِست را با «تست واحد خودکارسازی شده» (Automated unit Testing) انجام داد.
بهطور ایدهآل، باید برای هر بخش یا قطعه از کدهای منبع برنامه خود، تستهای مجزایی انجام شوند. این تستها را باید هر بار که تغییری در کدها اعمال میشود، دوباره انجام دهیم. به این طریق، اگر تست به درستی طراحی و نوشته شده باشد، میتوان به محض رخ دادن باگ جدید، آن را شناسایی کرد. بنابراین پیدا کردن منشأ وقوع باگ و دیباگ کردن آن بسیار سادهتر خواهد شد.
اگر تستهای خودکارسازی شده نداشته باشیم (البته این کار برای ساخت نرمافزارهای با کیفیت ضروری است)، حداقل باید خودمان به صورت دستی کدها را تست کنیم و لازم است تمام تعاملات ممکنی بازتولید شوند که کاربر میتوانست داشته باشد تا مطمئن شویم که باگ واقعاً و به طور موثر از بین رفته و Debug کردن به درستی انجام شده است.
اهمیت کدنویسی منظم و اصولی در دیباگ چیست ؟
بهترین راه برای دیباگ کردن و غلبه بر باگها این است که در وهله اول از ایجاد آنها جلوگیری و اجتناب کنیم. برای تمام برنامهنویسان، نوشتن کدهایی که در آنها عدم وجود باگ تضمین شده باشد، غیرممکن است؛ اما راهکارها و ترفندهایی برای کاهش احتمال وقوع باگ وجود دارد.
یک نقطه خوب برای شروع، استفاده از اصول KISS ،DRY و SOLID است. تاکنون کتابهای بسیاری برای آموزش این اصول منتشر شده است، اما به طور خلاصه، KISS ،DRY و SOLID از جمله اصولی به حساب میآیند که هدف آنها سادهسازی توسعه نرمافزار، آسان کردن درک کدها، تسهیل در امر نگهداری و مراقبت از نرمافزار و در نهایت، کمینهسازی حداکثری وقوع باگ است.
کدنویسی طبق اصل DRY برای دیباگ چیست ؟
کوتهنوشت «DRY» از عبارت «Don't Repeat Yourself» به معنی «کار تکراری انجام نده» گرفته شده است. خیلی ساده، این اصل برنامه نویسی، بیان میدارد که باید از تکرار کدهای یکسان تا حد امکان پرهیز کنیم. برای مثال، اگر ببینیم که داریم همان عملیات قبلی را دوباره و دوباره در بخشهای مختلف کدهای خود تکرار میکنیم، یک رویکرد بهتر این خواهد بود که سطح انتزاع آن منطق خاص را در قالب تابع را افزایش دهیم. در واقع به جای اجرای مستقیم عملیات روی بخشهای مختلف کدهای خود، تابع مربوطه را فراخوانی میکنیم.
به این ترتیب، اگر باگ یا رفتار غیرمنتظرهای در آن عملیات خاص رخ دهد، آنوقت میدانیم که باگ تنها در یک قطعه خاص از کدها یعنی همان تابع مربوطه ایجاد شده است و بنابراین باگهای زیادی در تمام بخشهای مختلف کدهای منبع برنامه ما به وجود نخواهند آمد.
تا حد امکان رعایت ساده نویسی برای نوشتن کدها
اصطلاح «KISS» کوتهنوشت عبارت «Keep it Simple Stupid» و به معنی «احمقانه ساده بنویس» است. با رشد و بزرگتر شدن نرمافزار، به ناچار برنامه پیچیدهتر میشود. با اضافه شدن قابلیتهای جدید از پیش برنامهریزی نشده و با توجه به اینکه برنامهنویسان مختلفی روی کدها کار میکنند، منطقهای مختلف و روشهای متفاوتی برای اجرای وظایف در داخل یک پروژه واحد به وجود میآید.
این باعث میشود درک کدها، نگهداری و کار با آنها دشوارتر شود. وقتی درک کدها دشوار شود، احتمال پیادهسازی فرضیههای اشتباه و ایجاد باگ هم بیشتر خواهد شد. همیشه باید هدف این باشد که نرمافزاری خوانا و قابل درک توسعه دهیم، نرمافزار و محصولی که نه تنها برای خودمان، بلکه برای همگان واضح و روشن باشد.
باید این مسئله را در نظر گرفت که در آینده ممکن است نیاز باشد شخص دیگری با کدهایی که ما نوشتهایم کار کند، بنابراین باید تا حد امکان کار را برای آن فرد آسان کرد تا بتواند آنچه انجام شده است را درک کند. گاهی ممکن است حتی خود برنامهنویس هم بعد از چند ماه به یاد نیاورد که سعی داشته مثلاً با یک تابع خاص چه کاری انجام دهد.
همچنین باید بدانیم که هیچ برنامه نرمافزاری برای همیشه به یک شکل باقی نخواهد ماند. تغییر جزء طبیعت نرمافزار به حساب میآید و ذات نرمافزار به این صورت است که باید در طول زمان با قابلیتهای جدید بهبود یابد. بنابراین باید کدها را بهگونهای نوشت که در صورت نیاز بتوان به راحتی آنها را تغییر داد.
علاوه بر این، هر وقت بتوانیم راه آسانتری برای اجرای وظایف یکسان پیدا کنیم، بهتر است کدهای قبلی را تغییر و بهبود دهیم. شاید پس از اضافه کردن چند ويژگی و قابلیت جدید، آن طراحی که ابتدا در ذهن بوده است دیگر بهترین گزینه نباشد. یک مسئله جالب دیگر در خصوص کدنویسی این است که هیچ چیز روی سنگ حک نشده است و میتوان موارد لازم را هر وقت که نیاز باشد تغییر داد. بنابراین باید از این مسئله تا حد امکان بهره برد و به بازسازی مداوم کدهای خود در جستجوی یافتن رویکردهای سادهتر عادت کرد. از جمله مفاهیم عملی و کاربردی که به این امر کمک میکنند میتوان به موارد زیر اشاره کرد:
- استفاده از نامهای واضح و شفاف برای توابع و متغیرها
- «جداسازی دغدغهها» (Separation of Concerns) و تقسیم آنها در توابع مختلف و ماژولهای کد
- نوشتن کامنتهای کوتاه برای توضیح دادن کدهای خود، زمانی که وظایف مربوطه به طرز غیرقابل اجتنابی پیچیده هستند.
اصول SOLID یکی از اصول مهم برنامه نویسی شیگرا هستند که در دیباگ هم کاربرد دارند و بنابراین در ادامه مطلب دیباگ چیست به معرفی این اصول پرداخته شده است.
اصول SOLID برای دیباگ چیست ؟
SOLID مجموعهای از اصول است که بیشتر در «شی گرایی» (OOP) کاربرد دارد. اصول SOLID توسط «رابرت مارتین» (Robert C. Martin) بنیان گذاشته شده است که مؤلف بیانیه اجایل هم هست.
- حرف S در SOLID از ابتدای عبارت «Single Responsibility» (مسئولیت واحد) میآید که یعنی یک کلاس در برنامه نویسی باید فقط و فقط یک وظیفه خاص را بر عهده داشته باشد.
- حرف O مربوط به عبارت «Open Closed Principle» میشود که به معنی «اصل باز–بسته» است. یعنی باید بتوان رفتار یک کلاس را بدون ویرایش آن گسترش داد.
- حرف L نماینده عبارت «Liskov Substitution Principle» (اصل جایگزینی لیسکوف) است که یعنی کلاسهای مشتق شده باید برای کلاسهای پایهشان قابل جایگزینی باشند.
- حرف I هم مربوط میشود به «Interface Segregation» که همان «قاعده تفکیک رابطها» است. یعنی کلاینت هیچ وقت نباید وادار به پیادهسازی واسطی شود که از آن استفاده نمیکند یا کلاینتها نباید وادار شوند به متدهایی که استفاده نمیکنند وابستگی داشته باشند.
- حرف D در SOLID به عبارت «Dependency Inversion Principle» اشاره دارد که همان «اصل وارونگی وابستگی» است. طبق این اصل، موجودیتها باید به انتزاعها و نه به ادغامها وابستگی داشته باشند. این اصل بیان میدارد که ماژول سطح بالا نباید به ماژول سطح پایین وابسته باشد، بلکه آنها باید به انتزاعها وابسته باشند.
همانطور که بیان شد، اصول SOLID بیشتر از اینکه به طور کلی مرتبط با برنامه نویسی باشند، در واقع به برنامه نویسی شیگرا یا همان OOP مربوط میشود. در این مطلب قرار بر این نیست که به صورت عمقی به OOP پرداخته شود، اما به هر حال دانستن این اصول و در ذهن داشتن آنها بسیار مفید است. اکنون در ادامه پاسخ به پرسش دیباگ چیست به معرفی برخی ابزارها برای کمک به دیباگ کردن کدها پرداخته شده است.
حال زمان آن فرا رسیده است تا در ادامه مطلب دیباگ چیست به معرفی ابزارهای فنی رایج برای Debug کردن و نحوه استفاده از آنها بپردازیم.
ابزارهای فنی برای دیباگ چیست ؟
ابزارهای زیادی وجود دارند که میتوان از آنها برای کاهش احتمال ایجاد باگ در کدها استفاده کرد. همچنین، ابزارهای دیگری هم برای مقابله بهینهتر با باگهای فعلی ایجاد شده در برنامهها قابل استفاده هستند. در این راستا، اینجا به بررسی TypeScript، ابزار بسیار محبوب و کاربردی console.log پرداخته میشود و همچنین نگاهی به دیباگ کننده یا همان دیباگرهای داخلی ادیتور VS Code و مرورگر کروم هم خواهیم داشت.
ابزارها و مثالهایی که در این بخش ارائه شدهاند، مبتنی بر جاوا اسکریپت هستند، اما اصول شرح داده شده را میتوان برای هر نوع زبان برنامه نویسی دلخواهی به کار گرفت. همچنین باید بدانیم که امروزه تقریباً اکثر کد ادیتورها و مرورگرهای وب دارای دیباگرهای داخلی مخصوص به خودشان هستند. در این بخش تنها به بررسی و مرور VS Code و کروم پرداخته شده است، زیرا از همه محبوبتر هستند.
همچنین لازم است به این نکته اشاره شود که ابزارهایی برای دیباگ کردن انواع خاصی از اپلیکیشنها مثل React و ریداکس هم وجود دارند که افزونههای مرورگر به حساب میآیند و میتوان آنها را برای کمک به Debug کردن بهینهتر کدها به کار گرفت. اما بررسی و شرح آنها از حوصله این مقاله خارج است و احتمالاً در مطالب بعدی به آنها خواهیم پرداخت.
در این بخش از مطلب دیباگ چیست ابتدا به معرفی دیباگ در TypeScript پرداخته و سپس سایر ابزارها معرفی خواهند شد.
TypeScript چگونه به کدنویسی ساختارمند کمک می کند؟
در اینجا به این دلیل TypeScript به عنوان اولین ابزار معرفی شده است که ارتباط نزدیکی با بخش مربوط به «کدنویسی اصولی» (Clean Code) در این مطلب دارد. تنها قابلیت TypeScript این نیست که سیستم قدرتمندی از تعیین نوع را برای جاوا اسکریپت فراهم کند. علاوه بر این، به وسیله TypeScript کامپایلری هم اضافه میشود که شناسایی باگها و اشتباهات داخل کدها را حتی قبل از اجرای کدها انجام میدهد. تایپاسکریپت قابلیت تکمیل خودکار کدها را همه به خوبی فراهم میسازد و میتوان آن را یک ابزار مستندسازی خودکار در نظر گرفت. تنها برای مشاهده اندکی از قابلیتهای TypeScript، بهتر است در ادامه به مثال قبلی بازگردیم که در آن هنگام فراخوانی تابع، آرگومانها به درستی به تابع ارجاع داده نشده بودند.
همانطور که در اینجا ملاحظه میشود، حتی قبل از اجرای برنامه، TypeScript بلافاصله شناسایی میکند که یک آرگومان جا افتاده است و خطای زیر به برنامهنویس نشان داده میشود:
Expected 3 arguments, but got 2.ts(2554) index.ts(6, 64): An argument for 'age' was not provided.
این نوع پیامهای خطا در تایپاسکریپت بسیار مفید و کاربردی هستند، خصوصاً وقتی در حال کار روی پروژههای بزرگی هستیم که در آنها باید تعامل با APIهای زیادی برقرار شود یا زمانی که بخشهای زیادی در کدها وجود دارند، این موضوع بسیار حائز اهمیت است. بنابراین، اگر برنامهنویسان وب تنها به خود زبان جاوا اسکریپت عادت دارند، ممکن است در ابتدا تایپاسکریپت غیرضروری و تکراری به نظر برسد. اما در طولانی مدت، قطعاً استفاده از TypeScript به جای جاوا اسکریپت موجب صرفهجویی در زمان خواهد شد و به میزان زیادی از ایجاد باگ در کدها جلوگیری میشود.
در زیربخش بعدی از این بخش مطلب دیباگ چیست به آموزش دیباگ با کنسول میپردازیم.
چگونه از Console.log برای دیباگ کردن کدها استفاده کنیم؟
ثبت وقایع (لاگ کردن) کدها در کنسول، سادهترین راه برای دیباگ کردن است و اولین روشی به حساب میآید که برنامهنویسان معمولاً استفاده میکنند. ایده این روش به این صورت است که مقدار متغیرها، توابع، ورودیها و خروجیها چاپ میشوند تا منطقی که در ذهن داریم با آنچه مقایسه شود که واقعاً در کدها رخ میدهند. همچنین، این شیوه کمک میکند تا بتوان فرضیههای نادرست را مشخص کرد. اگر چه Console.log ابزاری ساده و ابتدایی است، میتوان با آن کارهای جالبی انجام داد که در ادامه به آنها پرداخته شده است. اگرconsole.log را فراخوانی کنیم، هر شیئی که به عنوان پارامتر ارجاع داده شده است در کنسول چاپ میشود.
1const arr = []
2console.log(arr) // []
3
4const populateArr = (elem1, elem2, elem3) => arr.push(elem1, elem2, elem3)
5console.log(populateArr) // [Function: populateArr]
6
7populateArr('John', 'Jake', 'Jill')
8console.log(arr) // [ 'John', 'Jake', 'Jill' ]
دستورconsole.tableبرای کار با آرایهها یا اشیا مفید است، چرا که اطلاعات را در داخل جدول تنظیم میکند و بنابراین میتوان به راحتی کلیدها-اندیسها و خصوصیتها-مقدارها را مشاهده کرد.
1const arr = ['John', 'Jake', 'Jill']
2console.table(arr)
3
4//┌─────────┬────────┐
5//│ (index) │ Values │
6//├─────────┼────────┤
7//│ 0 │ 'John' │
8//│ 1 │ 'Jake' │
9//│ 2 │ 'Jill' │
10//└─────────┴────────┘
11
12const obj1 = {
13 name: 'John',
14 age: 30,
15 job: 'Programmer'
16}
17
18const obj2 = {
19 name: 'Jason',
20 age: 32,
21 job: 'Designer',
22 faveColor: 'Blue'
23}
24
25const arr2 = [obj1, obj2]
26
27console.table( arr2 )
28// ┌─────────┬─────────┬─────┬──────────────┬───────────┐
29// │ (index) │ name │ age │ job │ faveColor │
30// ├─────────┼─────────┼─────┼──────────────┼───────────┤
31// │ 0 │ 'John' │ 30 │ 'Programmer' │ │
32// │ 1 │ 'Jason' │ 32 │ 'Designer' │ 'Blue' │
33// └─────────┴─────────┴─────┴──────────────┴───────────┘
وقتی موارد بسیاری به صورت همزمان لاگ میشوند، دستور console.group به صورت سازماندهیشده امکان مشاهده جزئیات را فراهم میکند.
1const arr1 = [22, 23, 24]
2const arr2 = [25, 26, 27]
3
4console.group('myArrays')
5console.log(arr1)
6console.log(arr2)
7console.groupEnd()
8
9
10const obj1 = {
11 name: 'John',
12 age: 30,
13 job: 'Programmer'
14}
15
16const obj2 = {
17 name: 'Jason',
18 age: 32,
19 job: 'Designer',
20 faveColor: 'Blue'
21}
22
23console.group('myObjects')
24console.log(obj1)
25console.log(obj2)
26console.groupEnd()
27
28// myArrays
29// [ 22, 23, 24 ]
30// [ 25, 26, 27 ]
31// myObjects
32// { name: 'John', age: 30, job: 'Programmer' }
33// { name: 'Jason', age: 32, job: 'Designer', faveColor: 'Blue' }
همچنینconsole.assert هم برای زمانی کاربرد دارد که میخواهیم شرطهای برنامه را تست کنیم. این دستور ۲ آرگومان دریافت میکند که اولی یک شرط است و دومی پیامی است که در صورت اشتباه بودن شرط، ثبت خواهد شد.
1const arr1 = [22, 23, 24]
2
3console.assert(arr1.indexOf(20) !== -1, '20 is not in my array')
4// Assertion failed: 20 is not in my array
دستورهای console.warn و console.error هم وقتی کاربرد دارند که خطاها را در کدهایمان دیباگ میکنیم. دستور console.warn خطا را با پسزمینه زرد رنگ چاپ خواهد کرد و console.error هم خطا را با پسزمینه قرمز قرمز نشان میدهد.
1console.warn('No biggie') // No biggie
2console.error(new Error('Error detected'))
3
4// Error: Error detected
5// at Object.<anonymous> (/home/German/Desktop/ger/code/projects/test.js:6:15)
6// at Module._compile (node:internal/modules/cjs/loader:1101:14)
7// at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
8// at Module.load (node:internal/modules/cjs/loader:981:32)
9// at Function.Module._load (node:internal/modules/cjs/loader:822:12)
10// at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
11// at node:internal/main/run_main_module:17:47
حال در بخش بعدی از مطلب دیباگ چیست به دیباگ در VsCode پرداخته شده است.
چگونه از دیباگر ویژوال استودیو کد استفاده کنیم؟
با بزرگتر و پیچیدهتر شدن اپلیکیشنی که در حال ساخت آن هستیم، استفاده از Console.log چندان بهینه نخواهد بود. برای کمک به مقابله با باگها، ابزارهایی به نام «دیباگر» (Debugger) توسعه داده شدند. دیباگرها در واقع برنامهها یا نرمافزارهایی هستند که میتوانند کدهای برنامهنویسان را بخوانند، خط به خط آنها را مرور کنند و تمام اطلاعات مورد نیاز را در طول مسیر مورد بررسی قرار دهند. منظور از بررسی اطلاعات، مثلاً این است که مقدار یک متغیر مورد ارزیابی قرار بگیرد.
دیباگر ویژوال استودیو اولین نمونه از دیباگر است که در این بخش به آن پرداخته میشود. برای دیباگ کردن برنامه نوشته شده با Node.js با فرض اینکه VS Code و Node.js در کامپیوتر ما نصب شده است، نیاز به نصب هیچ چیز اضافهای وجود ندارد، زیرا دیباگر Node.js به صورت داخلی در VS Code ارائه شده است.
اگر نیاز به دیباگ کردن برنامهای به زبان دیگر مثل پایتون یا جاوا وجود داشته باشد، معمولاً لازم است افزونه مخصوص به زبان در VS Code نصب شود. برای شروع، باید فایلی را انتخاب کنیم که میخواهیم دیباگ کنیم و سپس دکمه با آیکن باگ را کلیک میکنیم. این دکمه در تصویر زیر با رنگ قرمز متمایز شده است.
پس از آن، صفحه زیر به ما نمایش داده خواهد شد:
در این صفحه (تصویر بالا)، باید گزینه «Run and debug» انتخاب شود. این گزینه برنامه را در ادیتور برای ما اجرا میکند. باید این موضوع را هم در نظر گرفت که ميتوان یک فایلlaunch.jsonرا هم ایجاد کرد. این فایل به وسیله VS Code برای دانستن این مسئله استفاده میشود که چطور باید برنامه را اجرا کنم. برای چنین مثال آسانی، این کار ضروری نخواهد بود، اما باید بدانیم که این امکان هم وجود دارد. بعد از کلیک کردن دکمه «Run and debug» برنامه اجرا خواهد شد و به صفحه زیر میرسیم:
در بالاترین قسمت سمت چپ، تمام متغیرهای داخل برنامه هم در سطوح محلی و هم در سطوح سراسری در دسترس هستند.
در قسمت زیرین، فضایی خواهیم داشت که میتوان در آن عبارتهایی را تعریف یا اعلان کرد که به طور خاص قصد داریم بر آنها نظارت داشته باشیم. «عبارتها» (Expression) میتوانند هر چیزی مثل متغیرهای خاص یا توابعی باشند که میخواهیم حواسمان به آنها باشد و آنها را نظارت کنیم تا بتوان ارزیابی کرد که آنها در حین اجرای برنامه ما چگونه تغییر میکنند. برای مثال، وقتی متغیری به نامarr در برنامه اضافه میشود، VS Code مقدار آن متغیر را در این بخش به ما نشان خواهد داد.
در قسمت زیرین هم بخش «پشته فراخوانی» (Call Stack)، اسکریپتهایی که در حال بارگذاری هستند و «نقاط گسست» (Breakpoint) وجود دارند که در کدها قرار داده شدهاند. در ادامه خواهیم دید که نقاط گسست دقیقاً چه هستند.
پیش از ارائه ادامه آموزش دیباگ در VsCode در این بخش از مطلب دیباگ چیست بهتر است در زیربخشی به این سوال پاسخ دهیم که نقطه گسست برای دیباگ چیست .
نقطه گسست برای دیباگ چیست ؟
نقاط گسست یا همان Breakpointها تاثیر بسزایی در استفاده مفیدتر از دیباگرها دارند. همانطور که از نامش پیدا است، اینها نقاطی هستند که میتوان در کدهای خود آنها را تعریف یا اعلان کرد و در این نقاط، دیباگر اجرای برنامه را متوقف میکند. وقتی که برنامه متوقف میشود، میتوان تمام اطلاعاتی که قبلاً اشاره شد را دقیقاً در همان وضعیتی بررسی کرد که در لحظه توقف دارا هستند. بنابراین، نقاط گسست اجازه میدهند تا بتوان اطلاعات را به صورت واقعی و به همان شکلی بررسی کرد که برنامه با استفاده از آنها کار میکند و نیازی به ثبت هیچ چیزی در کنسول هم نخواهیم داشت. در نتیجه، قابلیت نقطه گسست امکانی بسیار شگفتانگیز است.
نقاط گسست به وسیله نقطههای قرمز کوچکی در سمت چپ شماره خطوط کد مشخص میشوند. همچنین در بخشی با نام BREAKPOINTS که در تصویر بالا مشاهده میشود نیز میتوان نقاط گسست تعیین شده در برنامه را ملاحظه کرد. بهطور پیشفرض وقتی که دیباگر را اجرا میکنیم، یک نقطه گسست در آخرین خط برنامه ایجاد میشود. برای اضافه کردن نقاط گسست بیشتر، تنها کافی است در سمت چپِ شماره خطی کلیک کنیم که میخواهیم دیباگر در آنجا متوقف شود.
حالا وقتی که دیباگر را اجرا کنیم، مشابه تصویر زیر مشاهده خواهد شد که پیکانی کوچک به سمت چپ در بالای اولین نقطه گسست ظاهر میشود. این پیکان محلی که اجرای برنامه در آن متوقف شده است را مشخص میکند.
در قسمت بالای صفحه، دکمههای کنترلی قرار دارند که به ما اجازه خواهند داد تا در طول برنامه گام به گام از یک نقطه گسست تا نقطه گسست دیگر حرکت کنیم.
در ادامه، کارکرد هر یک از این دکمههای کنترلی شرح داده شدهاند:
- دکمه «Continue» برنامه را اجرا میکند و تنها در نقاط گسست تعریف شده توسط برنامهنویس متوقف میشود.
- در مورد دکمه «Step Over»، اگر فراخوانی تابع وجود داشته باشد، آن را اجرا خواهد کرد و نتیجه را باز میگرداند. با استفاده از این دکمه، گامها و مراحل وارد خطوط داخل تابع نمیشوند. در این حالت، فقط مستقیماً به مقدار بازگشتی تابع مراجعه میشود.
- اما دکمه کنترلی «Step Into» خط به خط وارد تابع میشود تا وقتی که تابع خروجی را بازگرداند و سپس به خط بعد از خط مربوط به فراخوانی تابع در برنامه اصلی میرود.
- در مورد دکمه «Step Out» اگر وارد یک تابع شده باشیم، میتوان از باقی اجرای تابع عبور و مستقیماً به مقدار بازگشتی مراجعه کرد.
- کارکرد دکمه «Restart» به این صورت است که دیباگر را دوباره از بالاترین نقطه اجرا میکند و دکمه «Stop» هم برای خروج از دیباگر استفاده میشود.
به این ترتیب دیباگر قدرتمند VS Code هم در این بخش تا حد امکان آموزش داده شد. همانطور که ملاحظه میشود، با استفاده از این ابزار میتوانیم اطلاعات بسیاری را به طور همزمان بررسی و ارزیابی کنیم و این کار تنها با قرار دادن نقاط گسست در هر جایی که بخواهیم بدون نیاز به استفاده از هیچگونه Console.log قابل انجام است. حال در ادامه به معرفی و توضیح دیباگر کروم پرداخته شده است.
اکنون در ادامه مطلب دیباگ چیست به شرح نحوه دیباگ کردن در کروم پرداخته شده است.
آموزش Debug کردن با مرورگر کروم
برای Debug کردن در کروم، لازم است کار را با باز کردن برنامه کاربردی خود در مرورگر کروم آغاز کنیم. در اینجا برای آموزش دیباگر کروم یک فایل ساده HTML ایجاد شده که فایل جاوا اسکریپت هم به آن پیوند داده شده است. سپس باید «Developer Tools» را باز کرد که این کار را میتوان با استفاده از کلیدهای میانبر «Ctrl+Shift+i» یا راست کلیک کردن و زدن گزینه «Inspect» انجام داد. در انتها هم لازم است به سربرگ «Sources» مراجعه شود تا در نهایت چیزی شبیه به تصویر زیر را مشاهده کنیم.
در سمت چپ میتوان فایلهای موجود در اپلیکیشن خود را ملاحظه کرد. در این مثال خاص، تنها یک فایل HTML و فایل جاوا اسکریپت وجود دارد. در قسمت میانی هم میتوان کدهای فایل انتخاب شده را مشاهده کرد. در سمت چپ هم مجموعهای از اطلاعاتی بسیار مشابه با آنچه وجود دارد که در VS Code وجود داشت. برای قرار دادن نقطه گسست، باید بالای خطی کلیک کنیم که میخواهیم اجرای دیباگر در آن متوقف شود. در مرورگر کروم، نقاط گسست به صورت پیکانهای آبی رنگ در بالای شماره خطوط قابل شناسایی هستند.
سپس اگر صفحه را بازنشانی (رفرش) کنیم، اسکریپت در اولین نقطه گسست متوقف خواهد شد و آن وقت اجازه خواهیم داشت تا با استفاده از کنترلها در طول آن نقل مکان کنیم که این دقیقاً در VS Code هم به همین شکل عمل میکرد.
همانطور که ملاحظه شد، دیباگرهای کروم و VS Code بسیار شبیه به هم عمل میکنند و بنابراین اینکه کدام یک بهتر است بیشتر به سلایق افراد بستگی دارد. اکنون در انتهای مطلب دیباگ چیست اشاره مختصری به یکی از روشهای دیباگ آنلاین پایتون هم شده است.
دیباگ آنلاین پایتون با Colab
برای دیباگ آنلاین پایتون میتوان از دیباگر آنلاین گوگل Colab استفاده کرد. این ابزار آنلاین تقریباً چیزی شبیه به Jupyter Notebook است که میتوان از طریق اینترنت به آن دسترسی داشت. تنها با جستجوی عبارت Colab در گوگل و کلیک کردن روی اولین نتیجه، میتوان وارد محیط توسعه و کد ادیتور Colab شد. برای انتقال کدهایمان به Colab به راحتی تنها روی گزینه Code در نوار ابزار این سرویس کلیک و کدها را در باکس کد ایجار شده کپی میکنیم.
برای اجرا و دیباگ آنلاین پایتون هم تنها کافی است روی آیکنی که شبیه به علامت پخش در ضبط صوت است کلیک کنیم و به این ترتیب کدها اجرا میشوند و در صورت وجود باگ، پیغام خطا در پایین باکس کدها نمایش داده میشود. با خواندن خطاها و مشخص شدن اینکه در کدام خط از کدها خطا رخ داده است، میتوان دیباگ آنلاین پایتون را انجام داد. مثلاً در تصویر زیر کدها در Colab به درستی اجرا شدهاند و باگی وجود نداشته است.
جمعبندی
دیباگ کردن یکی از فعالیتهای اصلی و مهمی است که برنامهنویسان انجام میدهند. به همین دلیل به نظر میرسد لازم باشد بیشتر در مورد آن بیاندیشیم. در واقع به جای اینکه فقط در هنگام وقوع باگها به آنها واکنش نشان دهیم کافی نیست و باید Debug کردن را به طور بسیار بهینهتری انجام بدهیم. در این نوشته مشخص شد که دیباگ چیست و میتوان کارهای بسیاری را هم به لحاظ ذهنی و هم به لحاظ فنی انجام داد تا در نهایت بتوانیم به دیباگرهای بهتری تبدیل شویم. امیدواریم درک درستی نسبت به اینکه دیباگ چیست بدست آمده و این نوشته مفید واقع شده باشد.