ماژولها در Crystal دو کاربرد دارند:
کاربرد اول، ساختن یک فضای نام برای جلوگیری از تداخل اسمها است. با این حال، کد را هم گروهبندی میکند و همین درک هدف کد را آسانتر میکند.
کاربرد دوم، تعریف میکسینها برای به اشتراک گذاشتن کد با نوعها است.
ماژولها شبیه کلاسها هستند، اما تفاوت اصلی این است که نمیتوان آنها را نمونهسازی کرد و در نتیجه متغیر نمونهای ندارند.
برای اعلام یک ماژول، از کلیدواژهی module استفاده میکنید و بعد از آن اسم ماژول را مینویسید.
module Foo
end
فضای نام روشی برای گروهبندی کد است.
این کار از تداخل اسمها جلوگیری میکند و درک هدف کد را آسانتر میسازد.
وقتی میخواهید به ثابت یا کلاسی دسترسی پیدا کنید که داخل یک فضای نام قرار گرفته است، از عملگر :: استفاده میکنید.
module Foo
class Bar
end
end
Foo::Bar.new
این کار میتواند مفید باشد، برای مثال وقتی چندین کلاس به یک کارکرد «پایه»ی یکسان نیاز دارند یا وقتی باید کد میان کلاسهای بیربط به اشتراک گذاشته شود. یا وقتی میخواهید کد را میان کلاسهایی به اشتراک بگذارید که به هم مربوط نیستند.
دو روش متفاوت برای استفاده از یک ماژول بهعنوان میکسین وجود دارد: روش اول استفاده از کلیدواژهی 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"