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"