স্কোপ হলো সকল রুবি ডেভেলপারের জন্য বুঝতে গুরুত্বপূর্ণ একটি কনসেপ্ট।
কেন?
কারণ এটি অনেক এরর মেসেজ এবং বিভ্রান্তির উৎস।
স্কোপ কী?
স্কোপ বলতে কোনো নির্দিষ্ট সময়ে কোন ভেরিয়েবলগুলো অ্যাক্সেসIBLE বোঝায়।
বিভিন্ন ধরনের ভেরিয়েবলগুলোর স্কোপ ভিন্ন হয়।
একটি স্কোপ খুব সংকীর্ণ (লোকাল ভেরিয়েবল) বা খুব rộng (গ্লোবাল ভেরিয়েবল) হতে পারে।
স্টেট মিউটেশন এবং নেম কলিশন থেকে বাঁচতে আপনাকে ন্যূনতম স্কোপ ব্যবহার করা উচিত।
নিচে স্কোপ কীভাবে আপনার রুবি কোডকে প্রভাবিত করে তার উদাহরণগুলো দেওয়া হলো।
লোকাল ভেরিয়েবল স্কোপ
লোকাল ভেরিয়েবলের সবচেয়ে সংকীর্ণ স্কোপ থাকে।
নির্দিষ্টভাবে, মেথডের ভিতরে ডিফাইন করা লোকাল ভেরিয়েবল মেথড রিটার্ন করার পর আর অস্তিত্বে থাকে না।
এখানে একটি উদাহরণ:
a = 50 def apple a = 100 puts a end
apple কী প্রিন্ট করবে তা চিন্তা করুন।
উত্তরটি:
যখন আপনি apple কল করবেন এটি সবসময় 100 প্রিন্ট করবে।
তথ্য হলো a মেথডের বাইরে 50 হিসেবে ডিফাইন করা হলেও সেটির a ভেরিয়েবলের ওপর মেথডের ভিতরে কোনো প্রভাব নেই।
এগুলো দুটি আলাদা ভেরিয়েবল।
আপনি স্কোপকে একটি সাবান বাবল হিসেবে ভাবতে পারেন... এই প্রথম a = 50 একটি বাবলে থাকে, তারপর যখন আপনি কোনো মেথড কল করেন, যেকোনো মেথড, আপনি একটি নতুন খালি বাবলে ঢুকেন।
আপনি নতুন বাবলে কোনো লোকাল ভেরিয়েবল নিয়ে যান না।
এবং যখন মেথড শেষ হয়...
বাবলটি ফুটে যায়।
বাবলের ভিতরের ভেরিয়েবলগুলো গায়ৌবে এবং আপনি সেগুলো আর অ্যাক্সেস করতে পারবেন না।
লোকাল ভেরিয়েবল এভাবে কাজ করে।
ইনস্ট্যান্স ভেরিয়েবল স্কোপ
ইনস্ট্যান্স ভেরিয়েবলের স্কোপ وسیর।
নির্দিষ্টভাবে, এগুলো একটি রুবি অবজেক্টের ভিতরে ডেটা শেয়ার করতে ব্যবহৃত হয়।
এখানে একটি উদাহরণ:
class Fruit def more_juice @quantity = 100 end def less_juice @quantity = 50 end end
এই উদাহরণে, @quantity দুটি মেথড more_juice এবং less_juice-র জন্য একই ভেরিয়েবল।
এটি মেথডগুলোর মাঝপথে একটি শেয়ারড ভ্যালু।
কিন্তু এই ক্লাসের বাইরে, এবং এমনকি ভিন্ন Fruit অবজেক্টগুলোর জন্য, @quantity আলাদা হবে।
উদাহরণ:
orange = Fruit.new apple = Fruit.new orange.more_juice apple.less_juice
প্রতিটি অবজেক্টের নিজস্ব সেট অফ ইনস্ট্যান্স ভেরিয়েবল থাকে।
সুতরাং এই উদাহরণে, orange-র @quantity হবে ১০০, আর apple-র হবে ৫০।
যেমন ভিন্ন মানুষের ভিন্ন নাম, বয়স, দেশ থাকে।
ব্লকে স্কোপ কীভাবে কাজ করে
স্কোপের ক্ষেত্রে ব্লকগুলো খুব আকর্ষণীয়।
আমাদের বাবল অনুমান অনুযায়ী, একটি ব্লক কারেন্ট বাবল থেকে লোকাল ভেরিয়েবলগুলো নিয়ে আসে।
আপনি সেগুলো অ্যাক্সেস ও পরিবর্তন করতে পারেন।
উদাহরণ:
a = [] 3.times { a << 1 } p a # [1, 1, 1]
কিন্তু...
বাবলটি সবশেষে ফুটে যায়, ব্লকের ভিতরে তৈরি করা যেকোনো নতুন লোকাল ভেরিয়েবল রিমুভ করে দিয়ে।
এটা আকর্ষণীয় না?
আমি কী বোঝাতে চাই তার উদাহরণ:
1.times { b = [1,2,3] } b # NameError
শুধু তো নয়, ব্লকগুলো সৃষ্টির মুহূর্তের বাবলটিও নিজেদের সাথে নিয়ে চলে।
এই ইফেক্টকে "ক্লোশার" বলা হয়।
মনে রাখবেন, এই "বাবল" হলো সোর্স কোডের নির্দিষ্ট পয়েন্টে অ্যাক্সেসIBLE সব ভেরিয়েবল들의 সংকলন।
এটি নিজে 스코প, যা একটি অবজেক্ট হিসেবে এনক্যাপসুলেট করা হয়েছে।
রুবিতে একে Binding বলা হয়।
রুবি বাইন্ডিংস কীভাবে ব্যবহার করবেন
এই আর্টিকেলে আমি আপনাদের সাথে বাইন্ডিং সম্পর্কে আরেকটি কনসেপ্ট শেয়ার করতে চাই।
আপনি আমরা যেসব বাবল নিয়ে কথা বলছি সেগুলো একটি রুবি অবজেক্টে, অর্থাৎ Binding ক্লাসের একটি অবজেক্টে সংরক্ষণ করতে পারেন।
উদাহরণ:
def banana a = 100 binding end banana.class # Binding
এই বাইন্ডিং অবজেক্টটিই হলো বাবল।
আপনি বাবলের ভিতর ঝাঁকিয়ে দেখতে পারেন কী আছে।
উদাহরণ:
banana.send(:local_variables) # [:a]
রেইলস স্কোপ কী?
রেইলসে স্কোপ রুবির স্কোপ থেকে আলাদা একটি জিনিস।
তাহলে, রেইলসে স্কোপ কী?
এটি একটি কাস্টম ডাটাবেস কোয়েরিকে নাম দেয়ার পদ্ধতি, যা ActiveRecord মেথডগুলো কম্পোজ করে তৈরি হয়।
এখানে একটি উদাহরণ:
class User < ApplicationRecord scope(:with_email) { where.not(email: nil) } end User.with_email
এটিকে রুবির স্কোপ কনসেপ্টের সাথে গুলিয়ে ফেলবেন না 🙂
সারসংক্ষেপ
আপনি রুবিতে স্কোপ এবং বাইন্ডিং অবজেক্ট সম্পর্কে শিখেছেন!
মনে রাখবেন স্কোপ নির্ধারণ করে যে কোনো নির্দিষ্ট সময়ে আপনি কোন ভেরিয়েবলগুলো অ্যাক্সেস করতে পারবেন।
এটি বাবলের মতো, লোকাল ভেরিয়েবলদের নিজস্ব বাবল থাকে, অন্যদিকে অবজেক্টগুলো ইনস্ট্যান্স ভেরিয়েবলের জন্য আরেকটি বাবল শেয়ার করে।
পড়ার জন্য ধন্যবাদ।