Crystal-এ মডিউল দুটি উদ্দেশ্যে ব্যবহৃত হয়:
প্রথম উদ্দেশ্য হলো নামের সংঘর্ষ এড়াতে একটি নেমস্পেস তৈরি করা। তবে এটি কোডকেও দলবদ্ধ করে, ফলে কোডটি কী কাজে ব্যবহার করা হয়েছে তা বোঝা সহজ হয়।
দ্বিতীয় উদ্দেশ্য হলো টাইপের মধ্যে কোড শেয়ার করার জন্য মিক্সিন ডিফাইন করা।
মডিউল ক্লাসের মতোই, তবে মূল পার্থক্য হলো এগুলো ইনস্ট্যান্টিয়েট করা যায় না, তাই এগুলোর ইনস্ট্যান্স ভ্যারিয়েবল থাকে না।
একটি মডিউল ডিক্লেয়ার করতে হলে module কিওয়ার্ডটি লিখতে হয়, তারপর মডিউলের নাম।
module Foo
end
নেমস্পেস হলো কোড দলবদ্ধ করার একটি উপায়।
এটি নামের সংঘর্ষ এড়ায় এবং কোডটি কী কাজে তা বোঝা সহজ করে।
নেমস্পেসের ভেতরে রাখা কোনো কনস্ট্যান্ট বা ক্লাস অ্যাক্সেস করতে চাইলে আপনি :: অপারেটরটি ব্যবহার করেন।
module Foo
class Bar
end
end
Foo::Bar.new
এটি তখন কাজে লাগে যখন, উদাহরণস্বরূপ, একাধিক ক্লাসের একই "base" কার্যকারিতা দরকার হয়, বা সম্পর্কহীন ক্লাসের মধ্যে কোড শেয়ার করা প্রয়োজন হয়। অথবা যখন পরস্পরের সাথে সম্পর্ক নেই এমন ক্লাসের মধ্যে কোড শেয়ার করতে চান।
মিক্সিন হিসেবে একটি মডিউল ব্যবহারের দুটি ভিন্ন উপায় আছে: প্রথমটি হলো include কিওয়ার্ডটি ব্যবহার করা, আর দ্বিতীয়টি হলো extend কিওয়ার্ডটি ব্যবহার করা।
দুটি পদ্ধতিই মডিউলটি যে টাইপ include বা extend করে, সেই টাইপের কাছে কনস্ট্যান্টগুলো উপলব্ধ করে দেয়।
Include করলে মডিউলের সমস্ত মেথড যে টাইপ মডিউলটি include করে, তার ইনস্ট্যান্স মেথড হিসেবে উপলব্ধ হয়।
include কিওয়ার্ডটি টাইপের শুরুতে থাকা উচিত, তারপর মডিউলের নাম।
module Foo
def foo
"foo"
end
end
class Bar
include Foo
end
Bar.new.foo # => "foo"
Extend কাজ করে include-এর মতোই, তবে মেথডগুলো ইনস্ট্যান্স মেথড হিসেবে উপলব্ধ করার বদলে সেগুলো ক্লাস মেথড হিসেবে উপলব্ধ করে।
extend কিওয়ার্ডটি টাইপের শুরুতে লিখতে হবে, তারপর মডিউলের নাম।
module Foo
def foo
"foo"
end
end
class Bar
extend Foo
end
Bar.foo # => "foo"
Crystal-এ একটি প্রচলিত প্যাটার্ন হলো মডিউলে extend self প্যাটার্নটি ব্যবহার করা।
এতে মডিউলের সমস্ত মেথড মডিউলটির নিজের ক্লাস মেথড হিসেবে উপলব্ধ হয়।
এর মানে হলো, def self.method_name সিনট্যাক্স ব্যবহার করে প্রতিটি মেথড আলাদাভাবে মডিউলের সাথে যুক্ত করতে হয় না।
module Foo
extend self
def foo
"foo"
end
end
Foo.foo # => "foo"
Bellebrook Basketball League একাধিক দলের একটি লিগ, যেখানে প্রতিটি দলের আছে খেলোয়াড়দের একটি তালিকা। নতুন একটি মৌসুম শুরু হতে চলেছে, আর গেমগুলোর টিকিট বিক্রি করার জন্য তাদের একটি নতুন টিকিটিং সিস্টেম তৈরি করতে হবে। গত মৌসুমে তারা স্টেডিয়ামের প্রবেশপথে টিকিট বিক্রি করত, কিন্তু জনপ্রিয়তা ব্যাপকভাবে বেড়ে যাওয়ায় এই মৌসুমে বাড়তি চাহিদা সামলাতে তারা অনলাইনে টিকিট বিক্রি করার সিদ্ধান্ত নিয়েছে।
লিগটি আপনার সাথে যোগাযোগ করে টিকিট বিক্রি সামলানোর একটি সিস্টেম তৈরি করতে বলেছে।
প্রথমে, টিকিট বিক্রি সামলানোর জন্য আপনাকে একটি টিকিটিং সিস্টেম তৈরি করতে হবে। টিকিটিং সিস্টেমটিকে বলতে হবে একটি গেমের জন্য কতগুলো টিকিট পাওয়া যাচ্ছে।
প্রতিটি গেমের জন্য TicketSystem নামের একটি ক্লাসের একটি ইনস্ট্যান্স তৈরি করতে হবে।
ইনিশিয়ালাইজড স্টেটে নিচের তথ্যগুলো থাকা উচিত:
পাওয়া যাওয়া টিকিটের সংখ্যা এবং ম্যাচটি কোন স্টেডিয়ামে খেলা হয় তা বোঝানো আর্গুমেন্ট থেকে একটি ইনিশিয়ালাইজড স্টেট তৈরি করুন।
ইনিশিয়ালাইজড স্টেটটি @tickets_available ও @stadium ইনস্ট্যান্স ভ্যারিয়েবল নিয়ে গঠিত হওয়া উচিত।
এগুলোতে যথাক্রমে দেওয়া প্রথম ও দ্বিতীয় আর্গুমেন্টটি থাকা উচিত।
TicketSystem.new(100, "Bellebrook")
# => #<TicketSystem:0x10f0b8 @tickets_available=100, @stadium="Bellebrook">
প্রথমে, নির্দিষ্ট একটি গেমের জন্য পাওয়া যাওয়া টিকিটের পরিমাণ রিটার্ন করে এমন একটি মেথড তৈরি করতে হবে।
আগে থেকে ডিফাইন করা ক্লাসটির উপরে TicketingReservation নামের একটি মডিউল ডিফাইন করুন।
এই মডিউলটি TicketSystem ক্লাসে ইনক্লুড করা উচিত।
মডিউলটির ভেতরে tickets_available নামের একটি মেথড ডিফাইন করুন।
এই মেথডটি পাওয়া যাওয়া টিকিটের পরিমাণ রিটার্ন করবে।
ticket_system = TicketSystem.new(100)
ticket_system.tickets_available
#=> 100
নির্দিষ্ট একটি গেমের জন্য টিকিট পাওয়া যাচ্ছে কি না তা যাচাই করে এমন একটি মেথড আপনাকে তৈরি করতে হবে। গেমটির জন্য ১০০টি টিকিট সংরক্ষিত রাখতে হবে। এর উদ্দেশ্য হলো স্টেডিয়ামের প্রবেশপথে টিকিট কেনা মানুষদের জন্য সব সময় টিকিট পাওয়া যাওয়া নিশ্চিত করা।
TicketingReservation মডিউলটির ভেতরে order_ticket? নামের একটি মেথড ডিফাইন করুন।
কমপক্ষে ১০০টি টিকিট পাওয়া গেলে মেথডটি true রিটার্ন করবে, অন্যথায় false রিটার্ন করবে।
কমপক্ষে ১০০টি টিকিট পাওয়া গেলে মেথডটি পাওয়া যাওয়া টিকিটের সংখ্যা ১ কমিয়েও দেবে।
ticket_system = TicketSystem.new(100)
ticket_system.order_ticket?
#=> true
টিকিটিং সিস্টেমে এমন বার্তা থাকতে হবে যা ব্যবহারকারীদের বুঝতে সহজ। আর বার্তাগুলো যেন ব্যক্তিগত লাগে, তাই সেগুলোতে ব্যবহারকারীর নাম থাকা উচিত।
টিকিট কেনাকাটা সফল হলে ব্যবহারকারী এমন একটি বার্তা পাবেন, যেখানে বলা থাকবে কেনাকাটা সফল হয়েছে, তাঁর টিকিট নম্বর কত, এবং গেমটি কোন স্টেডিয়ামে খেলা হয়। টিকিট নম্বরটি হবে অর্ডারের আগে পাওয়া যাওয়া টিকিটের সংখ্যা।
কেনাকাটা সফল হলে বার্তাটি দেখতে এমন হবে: {name}, your purchase was successful, your ticket number is #{ticket_number}, and the game is played at the {stadium_name} stadium..
কেনাকাটা ব্যর্থ হলে বার্তাটি দেখতে এমন হবে: {name}, your purchase was unsuccessful, there are not enough tickets available..
TicketingReservation, মডিউলটির ভেতরে order_message নামের একটি মেথড ডিফাইন করুন, যা ক্রেতার নাম ধারণ করা name আর্গুমেন্ট নেয়।
মেথডটি বার্তাসহ একটি স্ট্রিং রিটার্ন করবে।
ticket_system = TicketSystem.new(100, "Bellebrook")
ticket_system.order_message("John")
#=> "John, your purchase was successful, your ticket number is #100, and the game is played at the Bellebrook stadium."
Exercism-এ সাইন আপ করুন, Crystal ট্র্যাকের 26টি কনসেপ্ট142টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।