Skip to content

Chapter 24: JavaScript Browser Debugging

24-1: V8, করে না লেইট

শুধু বাইক থাকলে থাকবে চলবে না। বাইকার লাগবে। বাইকার না থাকলে বাইক চালাবে কে? আবার বাইক আর বাইকার দুইজনই আছে। কিন্তু বাইক চালানোর রাস্তা নাই, মাঠ নাই। তাহলে বাইক চলবে কোথায়?

জাভাস্ক্রিপ্ট হচ্ছে একটা বাইক। এইটার চালাবে ওয়েবসাইট। সেখানে বিভিন্ন কারণে চলবে। কিন্তু কোথায় চলবে? চলবে ব্রাউজারে।

ব্রাউজার একটা বিশাল দুনিয়া। এর ভিতরে কত কি যে ঘটে বলে শেষ করা যাবে না। এবং অনেক অনেক কাজ করে তার মধ্যে একটা বিশেষ জিনিস হচ্ছে জাভাস্ক্রিপ্ট ইঞ্জিন। যে জাভাস্ক্রিপ্ট কোডকে ইন্টারপ্রেট এবং এক্সিকিউট করে। আউটপুট দেখায়।

আরেকটু সহজ করে বললে JavaScript Engine হলো ব্রাউজারের ভিতর একটা সফটওয়্যার, যেটা জাভাস্ক্রিপ্ট কোডকে পড়ে, বুঝে, আর সেটা রান করায়। বর্তমান দুনিয়ায় সবচেয়ে জনপ্রিয় ইঞ্জিন হলো Google V8, যেটা ক্রোম এবং Node.js-এ ব্যবহার হয়।

জাভাস্ক্রিপ্ট ইঞ্জিন যেমন V8 ইঞ্জিন যখন কোন জাভাস্ক্রিপ্ট কোড পায় তখন সে তিনটা ধাপে কাজ করে।

১. পার্সিং (Parsing):

জাভাস্ক্রিপ্ট কোডকে টোকেন এ ব্রেক ডাউন করে এবং Abstract Syntax Tree (AST) তৈরি করে। একটু সহজ করে বললে কোড যেভাবে লেখা হইছে সেটাকে সে একটু ট্রি স্ট্রাকচার (অনেকটা গাছের মতো করে দেখতে) সেই স্টাইলে গুছিয়ে নেয়।

২. কম্পাইলেশন (Compilation):

AST-কে দেখে ইঞ্জিন বুঝে নেয়, কীভাবে এই কোডকে মেশিন ল্যাঙ্গুয়েজে কনভার্ট করবে। তারপর বাইটকোড বা মেশিন কোডে কনভার্ট করে।

মেশিন কোড বলতে বুঝায় যে কোড মেশিন (মানে কম্পিউটার বুঝতে পারে)। কারণ আমরা যে সব কোড লিখি এইটা কম্পিউটার সরাসরি বুঝে না। সে বুঝে শুধু Binary (0 এবং 1)। তাই আমাদের সব কোডকে আল্টিমেটলি Binary ফরম্যাটে (0 এবং 1) কনভার্ট করে নিতে হয়।

আমরা যেভাবে কোড লিখি সেটাকে বলে হাই লেভেল প্রোগ্রামিং ল্যাংগুয়েজ। কারণ এইগুলা মেশিন যেটা বুঝতে পারে সেটার চাইতে অনেক উপরে বা অনেক দূরে। আবার কিছু প্রোগ্রামিং ল্যাংগুয়েজ আছে যেগুলা মেশিন এর খুব কাছে। তাদেরকে লো লেভেল প্রোগ্রামিং ল্যাংগুয়েজ বলে।

আমরা যে কোড লিখি সেটাকে বলে source code আর আমাদের কোড কে মেশিন বুঝার জন্য এইটাকে প্রথমে মাঝামাঝি ধাপের একটা byteCode এ কনভার্ট করা হয়। তারপর সেটাকে আল্টিমেটলি মেশিন কোড বা বাইনারি কোড এ নিয়ে যেতে হয়।

JIT Compiler:

JIT (Just-In-Time) Compiler হলো একটা মেকানিজম, যেটা Source Code-কে Machine Code-এ রূপান্তর করার কাজ করে, Runtime-এ। এখানে Runtime বলতে বুঝায়: প্রোগ্রাম যখন চলছে, ঠিক তখনই Source Code-কে Compile করে Machine Code বানায়। যাতে কোড খুব দ্রুত এক্সিকিউট হয়।

আরো কয়েকটা বিষয় আছে। সেটা হচ্ছে compile শব্দটা কি? compile বলতে বুঝায় পুরা কোড একবারে মেশিন কোডে কনভার্ট করে তারপর রান হবে। এইটার অপোজিট সিস্টেম হচ্ছে Interpret করা। এইটা করলে কি হয়? এইটা করলে কোড এক লাইন এক লাইন করে এবং সাথে সাথে আউটপুট দিবে। এই প্রসেস একটু স্লো। এবং জাভাস্ক্রিপ্ট প্রথম দিকে Interpreted প্রোগ্রামিং ল্যাংগুয়েজ ছিল। তবে আস্তে আস্তে জাভাস্ক্রিপ্ট আরো পাওয়ারফুল হতে হতে এখন JIT (Just-In-Time) Compiler ইউজ করে। যাতে বাবার চলা কোডকে অপ্টিমাইজ করতে পারে। দ্রুত রান করতে পারে। সেজন্য V8 ইঞ্জিন JIT compiler পদ্ধতি ব্যবহার করে।

৩. এক্সিকিউশন (Execution):

এই ধাপে কম্পাইল করা কোডকে এক্সিকিউট করে এবং রেজাল্ট রিটার্ন করে। আর রান করার সময় ইঞ্জিন দেখবে, যদি কোনো কোড বারবার ইউজ হয় (যেমন লুপ), তখন সেটা Optimization করে।

Practice:

  1. জাভাস্ক্রিপ্ট এর কোড কিভাবে চলে?
  2. V8 ইঞ্জিন এর কাজ কি?
  3. JIT compiler কিভাবে কাজ করে?

24-2: দেবু কাকার Dev টুল

শুধু ওয়েবসাইট দেখার জন্য না; বরং ওয়েবসাইটের কোনো সমস্যা হলে সেটা চেক করার জন্যও কিন্তু ব্রাউজার ব্যবহার করতে হয়। কোনো একটা ব্রাউজারে রাইট ক্লিক করলে inspect একটা অপশন দেখায়, সেটাতে ক্লিক করলে ব্রাউজারের ভিতরে আলাদা একটা গোপন জগৎ খুলে আসবে তোর সামনে।

ডেভেলপার টুলস (Developer Tools) ব্রাউজার বা ওয়েব অ্যাপ্লিকেশনের জন্য অত্যন্ত গুরুত্বপূর্ণ একটি টুল, যা ডেভেলপারদের কোড, নেটওয়ার্ক রিসোর্স এবং অন্যান্য চেক করাতে কাজে লাগে।

মেজর ট্যাবসমূহ

১. Elements (এলিমেন্টস ট্যাব)

এই ট্যাবের মাধ্যমে HTML এবং CSS কীভাবে ওয়েবপেজে রেন্ডার হচ্ছে, তা দেখা যায়। HTML এলিমেন্টগুলো রিয়েল-টাইমে দেখতে পাবি, এডিট করতে পাবি, ওয়েবসাইটের ডিজাইন বা লেআউট চেইঞ্জ করে দেখতে পাবি। CSS কোড এখানে সরাসরি এডিট করতে পারবি। HTML এলিমেন্টের গঠন এবং স্ট্রাকচার দেখতে পারবি।

২. Console (কনসোল ট্যাব)

কনসোল হলো একটি ইন্টারেক্টিভ টার্মিনাল, যেখানে জাভাস্ক্রিপ্ট কোড লিখে আউটপুট দেখতে পাবি। আবার সেটার কী এফেক্ট হবে, সেটাও দেখতে পাবি। এ ছাড়াও কোনো কিছু কাজ না করলে প্রথম কাজ হয় কনসোলে এসে জাভাস্ক্রিপ্ট কোনো errors বা ওয়ার্নিং ম্যাসেজ দিচ্ছে কি না, সেটা দেখা। এ ছাড়াও জাভাস্ক্রিপ্ট কোড ডিবাগ করার সময় আউটপুট দেখার জন্য খুবই কাজে লাগে।

৩. Sources (সোর্স ট্যাব)

মূলত ওয়েবসাইটের সকল সোর্স ফাইল দেখার জন্য সোর্স ট্যাব ব্যবহৃত হয়। এই ট্যাব থেকে ডেভেলপাররা ওয়েবসাইটের জাভাস্ক্রিপ্ট ফাইল, ইমেজ এবং অন্যান্য সোর্স ফাইল দেখতে এবং ডিবাগ করতে পারে। ব্রেকপয়েন্ট তৈরি করে জাভাস্ক্রিপ্ট কোড ডিবাগ করতে পারে। স্টেপ-বাই-স্টেপ কোড এক্সিকিউশন করে চেক করতে পারে।

৪. Network (নেটওয়ার্ক ট্যাব)

নেটওয়ার্ক ট্যাব ওয়েবপেজের সমস্ত নেটওয়ার্ক অনুরোধ (HTTP, XHR, Fetch) দেখা এবং এনালাইসিস করার জন্য ব্যবহৃত হয়। এই ট্যাব ডেভেলপারদের ওয়েবপেজ লোড হওয়ার সময় কোন রিসোর্স কতটুকু সময় নিচ্ছে, তা চেক করতে সাহায্য করে। এ ছাড়া সার্ভার থেকে ডাউনলোড করা রিসোর্স ফাইল এবং তাদের সাইজ দেখার জন্য এই ট্যাব ইউজ করা হয়।

৫. Performance (পারফরমেন্স ট্যাব)

নাম দেখেই বুঝা যায়, ওয়েবপেজের পারফরম্যান্স এনালাইসিস করার জন্য পারফরম্যান্স ট্যাবটি ব্যবহৃত হয়। এটি দেখায়, কোন অংশে ওয়েবপেজ স্লো হয়ে গেছে এবং সেটাকে ফাস্ট করার জন্য কী কী করা যেতে পারে। CPU ও মেমরি কতটুকু ইউজ করতেছে, সেগুলা কীভাবে পারফরম্যান্স অপটিমাইজ করা যায়, তা এই ট্যাবে করা হয়।

৬. Application (অ্যাপ্লিকেশন ট্যাব)

অ্যাপ্লিকেশন ট্যাব ওয়েবপেজে স্টোরেজ-সংক্রান্ত তথ্য দেখা এবং ম্যানেজ করার জন্য ব্যবহৃত হয়। এর মাধ্যমে কুকিজ, লোকাল স্টোরেজ, IndexedDB ইত্যাদি ডেটা চেক করতে পারবি।

আমি জাস্ট সিম্পলভাবে কয়েকটা জিনিস বলেছি। তুই কাজ করতে করতে ডেভেলপার টুলস ইউজ করার পরিমাণ বাড়বে এবং এই বিষয়ে যত দক্ষ হবি, তুই তত ভালো ডেভেলপার হয়ে যাবি।

24-3: Web API ব্রাউজার API

Web API হলো কিছু ফাংশনালিটি, যেগুলা ওয়েব ডেভেলপমেন্টের অংশ হিসেবে দেয়া হয়। এদের কিছু ফাংশনালিটি শুধু ব্রাউজারে কাজ করে, সেগুলাকে ব্রাউজার API বলা হয়। তবে সাধারণভাবে সবগুলাকে web api বলে। আমি নিচে কয়েকটা গুরুত্বপূর্ণ ওয়েব API বলে দিচ্ছি। যেগুলার অনেক কিছুই তুই আগে থেকে জানস।

DOM (Document Object Model)

পুরা HTML ডকুমেন্টকে একটি অবজেক্টের আকারে নিয়ে আসে DOM। সাথে স্টাইল চেইঞ্জ করার অপশনও নিয়ে আসে DOM-এর মাধ্যমে। এইটা দিয়ে তুই ওয়েবসাইটের যেকোনো কিচ্ছু চেইঞ্জ করতে পারবি। নতুন কিছু যোগ করতে পারবি। সিম্পল একটা উদাহরণ হচ্ছে—

html
<h1 id="heading">Original Heading</h1>

উপরের html কোড চেইঞ্জ করার জন্য জাভাস্ক্রিপ্ট কোড।

javascript
let heading = document.getElementById("heading");
heading.innerText = "Super duper heading";

এছাড়াও ওয়েবসাইট এ ক্লিক, বিভিন্ন ধরনের ইভেন্ট, ডাইনামিক html বানানো, স্টাইল চেইঞ্জ করা, এনিমেশন, সহ ওয়েবসাইটকে ইন্টারেক্টিভ এবং ইন্টারেস্টিং করে তোলার বেশিরভাগ কাজ dom দিয়ে করা হয়।

Fetch API:

এই API ব্যবহার করে ডেভেলপাররা সহজেই নেটওয়ার্ক রিকোয়েস্ট করতে পারে। সার্ভার থেকে ডেটা আনতে বা সার্ভারে ডেটা পাঠাতে পারে। এইটাও অনেক জনপ্রিয় একটা ওয়েব API।

javascript
fetch("https://api.example.com/data")
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.log("Error:", error));

Local Storage:

কোন সিম্পলডাটা যদি ব্রাউজারে লম্বা সময় ধরে স্টোর করে রাখতে হয় তখন Local Storage খুব কাজে লাগে। যেমন ওয়েবসাইট কি লাইট মুডে নাকি ডার্ক মুডে চলবে। ওয়েবসাইট এ ইউজার যদি কোন নিদৃষ্ট ভাষা ইউজ করতে চায়। কিংবা ভিডিও প্লেয়ারের সাউন্ড লেভেল কত থাকবে। এইটাইপের জিনিস যেগুলা অনেকদিন ধরে ইউজারের কাজে লাগবে। Local Storage এ একবার ডেটা স্টোর করলে তা ব্রাউজার বন্ধ করে পুনরায় খোলার পরেও থেকে যায়। যতক্ষণ পর্যন্ত ইউজার নিজে গিয়ে লোকাল স্টোরেজের ডাটা না মুছে ফেলে ততক্ষণ পর্যন্ত এই ডাটা রয়ে যায়।

ডেটা কি-ভ্যালু পেয়ারে (key-value pairs) সংরক্ষিত হয়, যেখানে কি এবং ভ্যালু উভয়ই স্ট্রিং ফরম্যাটে থাকে।

নিচের কয়েক লাইন কোডের মাধ্যমে কিভাবে লোকাল স্টোরেজে ডাটা যোগ করতে হয়। কিভাবে লোকাল স্টোরেজ থেকে ডাটা বের করতে হয়। আবার চাইলে কোন একটা স্পেসিফিক ডাটা ডিলিট করতে চায় সেটা কিভাবে করবে। এমনকি চাইলে লোকাল স্টোরেজের সব ডাটাও ডিলিট করে দিতে পারবে।

javascript
//Save data to Local Storage
localStorage.setItem("username", "JohnDoe");

// get data from Local Storage
let user = localStorage.getItem("username");
console.log(user); // Output: JohnDoe

// Delete data from Local Storage
localStorage.removeItem("username");

// Delete All Data from Local Storage
localStorage.clear();

এইগুলা সবই জাভাস্ক্রিপ্ট দিয়ে ব্রাউজারে ফাংশনালিটি বা API ইউজ করে ওয়েবসাইট ইউজ করার এক্সপেরিয়েন্স অনেক ভালো করে ফেলে।

Session Storage:

সেশন স্টোরেজ লোকাল স্টোরেজের মতোই। শুধু একটা ডিফারেন্স। লোকাল স্টোরেজ ডাটা লম্বা সময় পর্যন্ত সেইভ করা থাকে। ব্রাউজার বন্ধ করে দিলেও চলে যায় না। অন্যদিকে সেশন স্টোরেজ এর ডাটা: ব্রাউজার বন্ধ করলে বা ব্রাউজারের ট্যাব ক্লোজ করলে আর থাকে না। বরং চলে যায়।

এটি Local Storage-এর মতোই সেশন স্টোরেজের ডাটা যোগ করা যায়। কোন ডাটা থেকে ভ্যালু নিয়ে আসা যায়। দরকার হলে একটা একটা করে ডাটা ডিলিট করা যায়। আবার চাইলে সব ডাটা একসাথেও ডিলিট করা যায়।

javascript
// Save Data to Session Storage
sessionStorage.setItem("authToken", "abcd1234");

// Get Data from Session Storage
let token = sessionStorage.getItem("authToken");
console.log(token); // Output: abcd1234

// Delete a Data from Session Storage
sessionStorage.removeItem("authToken");

// Delete All Data from Session Storage
sessionStorage.clear();

History API:

History API ব্রাউজারের ব্যাক এবং ফরওয়ার্ড বাটনের মাধ্যমে পেজ নেভিগেশন কন্ট্রোল করতে সাহায্য করে। history-এর মধ্যে বেশ কয়েকটা ইউজফুল ফাংশন দেয়া আছে।

  • pushState(): বর্তমান URL পরিবর্তন করে নতুন URL যোগ করে।
  • replaceState(): বর্তমান URL নতুন URL দিয়ে প্রতিস্থাপন করে।
  • go(): একটি নির্দিষ্ট ধাপ এগিয়ে বা পিছিয়ে যায়।
  • back(): ব্যাক বাটনের সমতুল্য।
  • forward(): ফরওয়ার্ড বাটনের সমতুল্য।
javascript
// Show the previous page in the browsing history
history.back();

// Show the next page in the browsing history
history.forward();

// Go to step back in the browsing history
history.go(-2);

// Go to the next page
history.go(1);

Practice:

  1. লোকাল স্টোরেজ আর সেশন স্টোরেজ এর মধ্যে ডিফারেন্স কি কি?
  2. Local Storage ব্যবহার করে ইউজারের ডার্ক মোড প্রেফারেন্স (on/off) সেভ কর। একটা key সেট কর। যেটার নাম হবে mode এবং সেটার ভ্যালু dark সেট কর। তারপরের আবার এই mode এর মান light সেট কর।
  3. Session Storage ব্যবহার করে ইউজারের লগইন টোকেন সেভ কর। টোকেনের নাম দে userToken এবং ভ্যালু দে abcd1234। পরে সেটা বের করে কনসোল লগ করে দেখা।
  4. Local Storage-এ ইউজারের নাম স্টোর কর যার নাম userName এবং ভ্যালু দে Alex। পরে সেই নামকে Local Storage থেকে রিমুভ কর।
  5. History API দিয়ে ব্রাউজারের দুই স্টেপ ব্যাক কর।

24-4: hug দ্য বাগ to ডিবাগ

যখন তুই একটা কোড লিখবি, সব কোডই তুই যেভাবে চাইবি, সেভাবেই কাজ করবে না। মাঝেমধ্যে এরর দিবে। আবার কোড দেখলে খুব সহজেই বুঝতে পারবি না। কী কারণে কোড ঠিকমতো কাজ করতেছে না।

তখন কোডের মধ্যে সমস্যা (বাগ: bug) খুঁজে বের করতে হবে। আর বাগ খুঁজে বের করে সেটাকে সল্ভ করার চেষ্টা করাকে ডিবাগ করা বলে। ডিবাগিং না জানলে প্রফেশনালি কাজ করতে পারবি না। ডিবাগ (debug) এর অনেক টেকনিক আছে এবং কাজ করতে করতে এইগুলাতে দক্ষ হয়ে উঠবি। আপাতত সিম্পল কয়েকটা টেকনিক সম্পর্কে জেনে রাখ।

Console.log() ব্যবহার করা

ডিবাগ করার সবচেয়ে সহজ, কমন এবং কম ইফেক্টিভ পদ্ধতি হচ্ছে— কোডের যে অংশে সমস্যা হচ্ছে, তার আশেপাশে অনেকগুলা console.log() বসিয়ে দিয়ে আউটপুট চেক করা। কোনো জায়গায় আউটপুট ঠিক হচ্ছে না, সেখানে গিয়ে কোড ঠিক করা।

যেমন নিচে আমি দুইটা সংখ্যার গুণ করার একটা ফাংশন লিখছি। এইখানে 5 আর 2-কে গুণ করলে 10 হওয়ার কথা, সেটা না করে আমাকে 7 রিটার্ন দিচ্ছে। এই সমস্যা বা বাগ কোথায় কী কারণে হচ্ছে, সেটা যদি আমি স্বাভাবিকভাবে না ধরতে পারি, তাহলে কোডের আশেপাশে বেশ কয়েকটা কনসোল লগ দিয়ে বুঝার চেষ্টা করবো।

javascript
function multiply(x, y) {
  console.log("X:", x);
  console.log("Y:", y);
  const result = x + y;
  console.log("result:", result);
  return result;
}

multiply(5, 2);

/* Output:
X: 5
Y: 2
result: 7
*/

জাস্ট আন্দাজে মান্দাজে একশটা কনসোল লগ বসালে তোর কোডের সমস্যা সমাধান হয়ে যাবে না। বরং কনসোল লগ এর আউটপুট কি কি আসছে। কোনটা কোনটা ঠিক আছে আর কোনটা কোনটা মনে হচ্ছে গড়বড় হচ্ছে সেটা বুঝার চেষ্টা করতে হবে। চেষ্টা করতে করতে এক সময় কনসোল এর বিষয়ে দক্ষ হয়ে উঠবি।

Breakpoint:

ব্রাউজার বা মডার্ন কোড এডিটর এর মধ্যে খুবই ইউজফুল একটা অপশন হচ্ছে Breakpoint। Breakpoint হচ্ছে এমন এক জায়গা, যেখানে তুই কোড চালানো থামিয়ে দিতে পারবি। ধর, তুই দেখতে চাচ্ছিস, একটা ফাংশন ঠিকমতো কাজ করছে কি না, তখন তুই সেই ফাংশনের ভিতরে প্রথম লাইনে বা যেখানে সমস্যা হতে পারে, সেখানে গিয়ে ব্রেকপয়েন্ট দিয়ে দিতে পারবি।

ব্রাউজারের DevTools-এ Source ট্যাবে গিয়ে Breakpoint সেট করতে পারিস। একবার কোড সেই Breakpoint-এ এসে থামলে তুই তখন পুরো সিস্টেমের অবস্থা দেখতে পারবি— ভ্যারিয়েবলগুলোর মান কী, কোন ফাংশন চালাচ্ছে ইত্যাদি।

Debugger:

হয়তো তোর সন্দেহ হচ্ছে কোডের এই জায়গায় কিছু একটা গণ্ডগোল হচ্ছে। বা এই লাইনের জন্যই সমস্যা হচ্ছে। এখন তুই চাইলে সেই লাইনের আগে বা পরে গিয়ে জাস্ট debugger এই শব্দটা লিখে দিবি। তাহলে কোড চলতে গিয়ে একজাক্টলি সেই জায়গায় থেমে যাবে। তখন তুই সেখানে গিয়ে কোডের বিভিন্ন ভেরিয়েবল এর মান, লজিক, অ্যারে, অবজেক্ট, স্কোপ ইত্যাদি চেক করতে পারবি। এবং ভুল ধরা তোর জন্য কিছুটা সহজ হয়ে উঠবে।

CallStack

CallStack হচ্ছে এমন এক ট্যুল, যেটা তুই ব্যবহার করে দেখতে পারবি, কোন ফাংশনটা কোথায় থেকে কল হচ্ছে। ধর, তুই একটা ফাংশন লিখছিস, সেটা অন্য একটা ফাংশন থেকে কল হচ্ছে। CallStack-এর মাধ্যমে তুই সেই কলের পুরো চেইন দেখতে পারবি।

ডিবাগিং করার সময় তুই কয়েকটা স্টেপ ফলো করতে পারিস, যেন কাজটা সহজ হয়

Error Message পড়া

প্রথমেই তুই Error Message ভালোভাবে পড়বি। Error Message তোর কোডে কোথায় সমস্যা হচ্ছে, সেটা দেখাবে, তাই এটা মনোযোগ দিয়ে পড়তে হবে।

Problem Isolation

তুই যদি অনেক বড় কোডে কাজ করিস, তাহলে প্রথমেই সমস্যার জায়গাটা বের করতে হবে। কোডের কোন অংশে সমস্যা, সেটা খুঁজে বের করতে পারলে বাকি কোড ঠিক রাখতে পারবি।

Test in Small Parts

কোডের ছোট ছোট অংশ নিয়ে টেস্ট কর। যেমন, ফাংশনের একটা অংশে সমস্যা হলে শুধু সেই অংশটা আলাদা করে চালিয়ে দেখ, কোথায় কী হচ্ছে।

Use Tools

তুই DevTools, Breakpoint, আর CallStack-এর মতো টুলগুলো ব্যবহার করবি। এগুলো তোর ডিবাগিং অনেক সহজ করে দেবে।

Consult Documentation

যদি কোনো মেথড বা ফাংশনের কাজ ঠিকমতো বুঝতে না পারিস, তখন ডকুমেন্টেশন দেখতে পারিস। অনেক সময় ভুল ফাংশন ব্যবহার করলে সমস্যার সমাধান মিলবে।

Released under the MIT License.