রুবিতে রেঞ্জ (Range) কী এবং এটি কীভাবে কাজ করে?
একটি রেঞ্জ হল একটি অবজেক্ট য একটি শুরুর মান এবং একটি শেষ মান ধারণ করে, এগুলো আপনাকে সেই দুটি মানের মাঝপথের সকল মান ধারণকারী একটি সিকোয়েন্স তৈরি করতে সাহায্য করে।
আপনি ১ থেকে ২০ পর্যন্ত যেতে পারেন, আবার "a" থেকে "z" পর্যন্ত যেতে পারেন।
এই আর্টিকেলে আপনি জানবেন:
- রুবি রেঞ্জ কীভাবে তৈরি করবেন
- রুবিতে
stepএবংinclude?মেথডগুলো কীভাবে ব্যবহার করবেন - রেঞ্জ কীভাবে আন্ডারলাইন কাজ করে
চলুন শুরু করি!
রেঞ্জ বোঝা
স্মরণ করানোর জন্য, রুবি রেঞ্জ সিনট্যাক্সটি এমন দেখায়:
(1..20)
একটি Range ডিফাইন করতে প্যারেনথেসিস বাধ্যতামূলক নয়।
কিন্তু আপনি যদি আপনার রেঞ্জের ওপর মেথড কল করতে চান তবে প্যারেনথেসিস লাগবে। অন্যথায়, আপনি রেঞ্জের ওপর না কল করে রেঞ্জের দ্বিতীয় এলিমেন্টের ওপর মেথড কল করছেন।
Range ক্লাস Enumerable মডিউল ইনক্লুড করে, তাই আপনাকে রেঞ্জকে অ্যারে কনভার্ট না করেই সকল পাওয়ারফুল ইটারেশন মেথড পাওয়া যায়।
রুবি Step মেথড
Range এর কিছু দরকারী মেথড আছে, যেমন step মেথড।
উদাহরণ:
(10..20).step(2).to_a # [10, 12, 14, 16, 18, 20]
এই মেথড ব্যবহার করে আপনি n ইনক্রিমেন্টে রেঞ্জের ওপর ইটারেট করতে পারেন, যেখানে n হল step-এ পাস করা আর্গুমেন্ট।
একটি নাম্বার রেঞ্জের ভেতরে আছে কিনা তা জানা
রেঞ্জের অন্যান্য জানা উচিত মেথডগুলো হল: cover? এবং include?।
এগুলো একই কাজ করে ভাবা ভুল হবে, কারণ এগুলো একই কাজ করে না।
include? মেথডটি সাদা করে যা আপনি আশা করবেন, রেঞ্জের ভেতরে ইনক্লুশন চেক করে। অর্থাৎ এটি সমান রেঞ্জকে Array-তে এক্সপ্যান্ড করে এবং চেক করে কীচু আছে কিনা।
কিন্তু cover? আলাদা, এটি শুধু রেঞ্জের ইনিশিয়াল এবং এন্ডিং ভ্যালু চেক করে (begin <= obj <= end), যা অপ্রত্যাশিত ফলাফল দিতে পারে।
উদাহরণ:
('a'..'z').include? "cc" # false ('a'..'z').cover? "cc" # true
cover? উদাহরণটি সমতুল্য:
"a" <= "cc" && "cc" <= "z"
এটি true রিটার্ন করার কারণ হল স্ট্রিংগুলো ক্যারেক্টার বাই ক্যারেক্টার কম্পেয়ার করা হয়। যেহেতু "a" "c" এর আগে আসে, তাই প্রথম "c" এর পরের ক্যারেক্টারগুলো মাথা ব্যাথা করবে না।
রুবিতে রেঞ্জ কীভাবে ইমপ্লিমেন্ট করা হয়
রেঞ্জ শুধু নাম্বার এবং লেটারের জন্য সীমাবদ্ধ নয়, আপনি যেকোনো অবজেক্ট ব্যবহার করতে পারেন যতক্ষণ না সেগুলো নিচের মেথডগুলো ইমপ্লিমেন্ট করে: <=> এবং succ।
উদাহরণস্বরূপ, একটি DateTime রেঞ্জ:
require 'time' t1 = DateTime.new t2 = DateTime.new + 30 next_30_days = t1..t2 # উদাহরণ ব্যবহার next_30_days.select(&:friday?).map(&:day)
তাহলে এটি কীভাবে কাজ করে? আসুন এই ইমপ্লিমেন্টেশনটি দেখি:
def range(a, b) # যদি প্রথম এলিমেন্ট দ্বিতীয়টির চেয়ে বড় হয় # তবে এটি একটি সিকোয়েনশিয়াল রেঞ্জ নয় return [] if a > b out = [] # দ্বিতীয় এলিমেন্ট প্রথমটির সমান হওয়া পর্যন্ত এডভান্স করুন while a != b out << a a = a.next end # শেষ এলিমেন্ট যোগ করুন (ইনক্লूसিভ রেঞ্জ) # এটি ইমপ্লিসিট রিটার্ন দিয়ে রেজাল্টও রিটার্ন করে out << a end p range 1, 10 p range 'a', 'z'
বুঝতে সুবিধার্থে আমি কিছু কমেন্ট যোগ করেছি।
আইডিয়া হল: আমরা প্রথম অবজেক্টের ওপর next মেথড কল করতে থাকি যতক্ষণ না সেটি দ্বিতীয়টির সমান হয়, অনুমানটি হল তারা শেষ পর্যন্ত মিলবে।
কাস্টম ক্লাস রেঞ্জ
অধিকাংশ সময় আপনি নাম্বার এবং ক্যারেক্টার রেঞ্জ ব্যবহার করবেন, তবে কাস্টম ক্লাসে রেঞ্জ কীভাবে ব্যবহার করা যায় সেটা জানা ভালো।
উদাহরণ:
class LetterMultiplier attr_reader :count include Comparable def initialize(letter, count) @letter = letter @count = count end def succ self.class.new(@letter, @count + 1) end def <=>(other) count <=> other.count end end a = LetterMultiplier.new('w', 2) b = LetterMultiplier.new('w', 8) # রেঞ্জের সকল আইটেম সহ অ্যারে প্রিন্ট করুন p Array(a..b)
মূল কথা হল: নিশ্চিত করুন যে আপনি <=> এবং succ মেথডগুলো সঠিকভাবে ইমপ্লিমেন্ট করেছেন।
আপনি যদি include? মেথড ব্যবহার করতে চান তবে আপনাকে Comparable মডিউল ইনক্লুড করতে হবে, যা ==, <, এবং > এর মতো মেথড যোগ করে (সব <=> মেথডের রেজাল্টের উপর ভিত্তি করে)।
উপসংহার
এই আর্টিকেলে আপনি শিখেছেন রুবিতে রেঞ্জ কীভাবে কাজ করে যাতে আপনি এগুলো ভালোভাবে বুঝতে পারেন এবং রেঞ্জ অপারেশন সাপোর্ট করা নিজস্ব অবজেক্ট ইমপ্লিমেন্ট করতে পারেন।
নিউজলেটার সাবস্ক্রাইব করা ভুলবেন না যাতে পরবর্তী পোস্ট মিস না হয় 🙂