প্রথম কয়েক বছর আমি ভাবতাম কোড রিভিউ মানে ভুল ধরা। কারও diff পড়বে, বাগ খুঁজে বের করবে, দেখিয়ে দেবে, তারা ঠিক করবে। একটা কোয়ালিটি গেট। উপকারী, একটু প্রতিদ্বন্দ্বিতামূলক, মূলত যুক্তির জন্য একটা বানান-পরীক্ষক।
এখন আর তা মনে করি না। কয়েক বছর অন্যের কাজ রিভিউ করতে করতে, ক্যারিয়ারের শুরুর দিকের ইঞ্জিনিয়ারদের মেন্টর করতে করতে ও টেবিলের অন্যপাশে বসে ইন্টার্নদের মূল্যায়ন করতে করতে রিভিউ আর বাগ খোঁজার বিষয় থাকল না — হয়ে উঠল এমন কিছু, যা একটি দলের একসঙ্গে ভাবার প্রধান উপায়ের কাছাকাছি। বাগগুলো প্রায় একটা পার্শ্বপ্রতিক্রিয়া। রিভিউয়ে আসলে যা তৈরি হয় তা হলো অভিন্ন বোঝাপড়া — এবং সেটা ভালো কোড লেখার চেয়ে সম্পূর্ণ আলাদা এক দক্ষতা।
যে প্রশ্নটি আমার কাছে বিষয়টাকে নতুন করে সাজাল
পরিবর্তনটা এল যখন diff পড়ার সময় "এটা কি সঠিক?" জিজ্ঞেস করা বন্ধ করে জিজ্ঞেস করতে শুরু করলাম "পরের মানুষটি কি ছয় মাস পর এটা বুঝবে?" — এবং প্রায়ই পরের মানুষটি হলো লেখক নিজেই, যে মনে রাখবে না কেন সে এসব করেছিল।
রিভিউয়ে আসলে যা তৈরি হয় তা হলো অভিন্ন বোঝাপড়া — এবং সেটা ভালো কোড লেখার চেয়ে সম্পূর্ণ আলাদা এক দক্ষতা।
এই দুটি প্রশ্ন প্রত্যাশার চেয়ে বেশি বার বিপরীত দিকে টানে। কোড নিখুঁতভাবে সঠিক হতে পারে অথচ একটা ছোট টাইম বোমা হয়ে থাকতে পারে: এমন এক চতুর one-liner যা বুঝতে দশ মিনিট লাগে, এমন এক নাম যা লেখকের কাছে নির্দিষ্ট কিছু বোঝায় আর বাকি সবার কাছে কিছুই নয়, এমন এক যুক্তি যার কেন পুরোপুরি লেখকের মাথায় থাকে, ফাইলে কোথাও নয়। এর কোনোটাই কোনো টেস্ট ফেল করায় না। এর সবটাই দলের কাছে পরে দাম নেয়। ছয়-মাসের প্রশ্নটা মাথায় রেখে রিভিউ শুরু করার পর আমি এমন এক শ্রেণির সমস্যা ধরতে শুরু করলাম, যেগুলো "এটা কি সঠিক" দিব্যি পাশ কাটিয়ে যায়।
সেরা মন্তব্যগুলো কেন প্রশ্ন হয়
শুরুতে আমার রিভিউ মন্তব্যগুলো ছিল নির্দেশ। "এটার নাম বদলাও।" "এটাকে একটা ফাংশনে বের করো।" "এটা memoize করা উচিত।" কারিগরিভাবে ঠিক আছে, কিন্তু সময়ের সঙ্গে ভালো টেকেনি।
নির্দেশের ধরনে দুটি সমস্যা ছিল। প্রথমত, কখনো কখনো প্রসঙ্গটা আমিই মিস করতাম — কোডটা যেভাবে ছিল তার একটা বাস্তব কারণ ছিল, আর আমার আত্মবিশ্বাসী নির্দেশ কেবল দেখাত যে আমি মন দিয়ে পড়িনি। দ্বিতীয়ত, নির্দেশ কথোপকথন বন্ধ করে দেয়। লেখক হয় মেনে নেয়, নয়তো তর্ক করে; দুই ক্ষেত্রেই কেউ কিছু শেখে না।
একটা প্রশ্ন বেশি কাজ করে। "এই array খালি হলে এখানে কী হবে?" — "খালি কেসটা সামলাও"-এর চেয়ে ভালোভাবে পৌঁছায়, আর একটা কারণেই ভালোভাবে পৌঁছায়: যদি সত্যিই বাগ থাকে, লেখক নিজে সেটা খুঁজে পায়, যা উত্তর হাতে ধরিয়ে দেওয়ার চেয়ে অনেক বেশি শেখায়। যদি না থাকে — যদি তারা আগেই উপরের দিকে সামলে রাখে — তাহলে ভুল নির্দেশ রেকর্ডে বসিয়ে দেওয়ার বদলে আমি কিছু শিখি। প্রশ্নটা মেনে নেয় যে লেখক এমন কিছু জানতে পারে যা আমি জানি না, আর এটা রিভিউকে দুজন মানুষের একসঙ্গে কোড বোঝার কথোপকথনে পরিণত করে, একজনের আরেকজনকে নম্বর দেওয়ায় নয়।
যা আটকায় আর যা কেবল আমার পছন্দ — এ দুটোকে আলাদা করা
এখানে একটা পার্থক্য আছে, যা না করলে চুপচাপ দলের সঙ্গে রিভিউয়ের সম্পর্ককে বিষিয়ে তোলে: "এটা ভাঙা" আর "আমি হলে অন্যভাবে লিখতাম" — এ দুটোর পার্থক্য।
auth চেক নেই বলে একটি মন্তব্য আর ভেরিয়েবলের নাম অন্যভাবে দিতে হতো বলে একটি মন্তব্য — এরা এক প্রজাতির নয়, আর এদের সমান ধরা ক্ষতিকর। যখন প্রতিটি নোট একই ওজন বহন করে, লেখক ভার-বহনকারী ফিডব্যাককে আপনার ব্যক্তিগত রুচি থেকে আলাদা করতে পারে না, তাই হয় তারা সবকিছুকে blocking ধরে ডুবে যায়, নয়তো সবকিছুকে ঐচ্ছিক ধরে যেটা গুরুত্বপূর্ণ ছিল সেটা মিস করে।
নিজের মন্তব্যে লেবেল দেওয়া শুরু করার পর আমি কাজ করার জন্য অনেক বেশি উপযোগী হয়ে উঠলাম। blocking সমস্যা blocking হিসেবেই বলা হয়। preference preference হিসেবে বলা হয় এবং স্পষ্টভাবে লেখকের সিদ্ধান্ত বলে চিহ্নিত করা হয় — "non-blocking, নিলে নাও না নিলে নেই।" ওই একটা অভ্যাস যেকোনো টুলিংয়ের চেয়ে রিভিউ সংস্কৃতির জন্য বেশি করে। এটা লেখককে ঠিক বলে দেয় আসল সীমারেখা কোথায়, আর আমাকে নিজের সঙ্গে সৎ হতে বাধ্য করে যে আমার কতগুলো মন্তব্য সত্যিই গুরুত্বপূর্ণ ছিল আর কতগুলো কেবল আমি কীভাবে জিনিস পছন্দ করি তা নিয়ে।
জুনিয়রদের কোড রিভিউ করা আমাকে নিজের সম্পর্কে যা দেখাল
ক্যারিয়ারের শুরুর দিকের ইঞ্জিনিয়ারদের কোড রিভিউ করা এক অদ্ভুত আয়না। আপনি দেখেন কেউ দীর্ঘ, স্পষ্ট, সামান্য আনাড়ি উপায়ে কিছু করছে — এবং প্রায় এক-তৃতীয়াংশ সময় আপনি বোঝেন যে দীর্ঘ উপায়টা আসলে সেই চতুর শর্টকাটের চেয়ে পরিষ্কার, যেটার দিকে আপনি অটোপাইলটে হাত বাড়াতেন।
জুনিয়র কোড "কেন" জোরে জিজ্ঞেস করে। এটা এখনো জানে না কোন কনভেনশনগুলো ভার-বহনকারী আর কোনগুলো কেবল অভ্যাস, তাই এটা দুর্ঘটনাক্রমে সবগুলোকেই প্রশ্ন করে। আমার নিজের অনেক "best practice" ওই নিষ্পাপ পরীক্ষার নিচে দেখা গেল এমন জিনিস যা আমি করতাম কারণ সবসময় করে এসেছি, তা টিকত বলে নয়, যখন কেউ ব্যাখ্যা করতে বাধ্য করত। যারা এখনো আমার অভ্যাস শোষণ করেনি তাদের রিভিউ করা ছিল সেই অভ্যাসগুলোর কোনটা আসল তা বোঝার ভালো উপায়গুলোর একটা।
এটা কীভাবে আপনার নিজের কোডে ফিরে আসে
সবচেয়ে অদ্ভুত প্রভাব হলো যথেষ্ট কোড রিভিউ করলে তা চুপচাপ আপনার লেখার ধরনকেই বদলে দেয়। আপনি একটা ফাংশন লিখতে শুরু করেন আর প্রথম লাইন শেষ করার আগেই মাথায় রিভিউ শুনতে পান। কেউ জিজ্ঞেস করবে ইনপুট খালি হলে এটা কী সামলায়। কেউ জিজ্ঞেস করবে এটা এখানে কেন। ওই নামটা পরের পাঠকের কাছে কিছুই বোঝাবে না। তাই কেউ জিজ্ঞেস করার আগেই আপনি কোডেই ওই প্রশ্নগুলোর উত্তর দিয়ে দেন।
এটা আমার জানা সবচেয়ে কার্যকর ফিডব্যাক লুপ, ঠিক এই কারণেই যে এটা শেষ পর্যন্ত রিভিউয়ারকে আর দরকার হয় না। যেসব মন্তব্য আপনি পেয়েছেন আর যথেষ্ট বার লিখেছেন সেগুলো প্রথম খসড়াতেই যে কণ্ঠস্বরের বিপরীতে আপনি সম্পাদনা করেন, তাতে পরিণত হয়।
রিভিউ কোথায় থামে
আমি এটাকে বাড়িয়ে বলতে চাই না, কারণ যে দল রিভিউয়ের উপর অতিরিক্ত ভরসা করে তারা একটা নির্দিষ্ট ভুল করে। রিভিউ একটা সরু-জানালার টুল। এটা একটা diff দেখে — এই পরিবর্তন, কোডবেসের এই মুহূর্তের বিপরীতে — এবং সেই মাপে এটা চমৎকার আর তার বাইরে অন্ধ। এটা আপনাকে বলবে না যে পুরো পদ্ধতিটাই ভুল, যে ফিচারটা এভাবে বানানো উচিত নয়, যে আর্কিটেকচারে পরিবর্তনটা পরিপাটিভাবে বসে সেটাই সমস্যা। কিছু রিভিউতে পৌঁছানোর সময় বেশিরভাগ গুরুত্বপূর্ণ সিদ্ধান্ত আগেই নেওয়া হয়ে গেছে।
ওই সিদ্ধান্তগুলো এমন কথোপকথনের অংশ যা কেউ কোড লেখার আগে হয় — একটা হোয়াইটবোর্ড, একটা ডিজাইন ডক, কারও ডেস্কে পাঁচ মিনিট। যেসব দলে কাজ করে আমি সবচেয়ে বেশি উপভোগ করেছি তারা রিভিউকে সেই শৃঙ্খলের একটা কড়ি হিসেবে দেখত, পুরো শৃঙ্খল হিসেবে নয়। যা ফাঁক গলে বেরিয়ে যায় রিভিউ তা ধরে। এটা কখনো একমাত্র জাল হওয়ার কথা ছিল না, আর এটাকে সেটা হতে বলাই হলো কীভাবে একটা খারাপ আইডিয়ার সেবায় ভালো কোড শিপ হয়ে যায়।