الیکسیر یک زبان با نوعدهی پویاست؛ یعنی نوع یک متغیر فقط در زمان اجرا بررسی میشود. با عملگر تطبیق = میتوانیم مقداری از هر نوع را به اسم یک متغیر متصل کنیم:
# Bound an integer value of 1
count = 1
# You may re-bind variables
count = 2
# You may re-bind any type to a variable
count = false
# Strings can be created by enclosing characters within double quotes
message = "Success!"
الیکسیر یک زبان برنامهنویسی تابعی است و ایجاب میکند که همهی توابع نامدار در یک ماژول تعریف شوند. کلیدواژهی defmodule برای تعریف یک ماژول به کار میرود. همهی ماژولها در زمان اجرا برای سایر ماژولها در دسترساند و برای اینکه بقیهی بخشهای برنامه آنها را ببینند به اصلاحکنندهی دسترسی نیازی ندارند. یک ماژول همانند یک کلاس در سایر زبانهای برنامهنویسی است.
defmodule Calculator do
# ...
end
توابع نامدار باید در یک ماژول تعریف شوند. کلیدواژهی def برای تعریف یک تابع نامدار عمومی به کار میرود.
هر تابع میتواند صفر یا چند آرگومان داشته باشد. مقدار آخرین عبارت در یک تابع همیشه بهصورت ضمنی برگردانده میشود.
defmodule Calculator do
def add(x, y) do
x + y
end
end
فراخوانی یک تابع با مشخص کردن ماژول و اسم آن و دادن آرگومانی برای هر یک از آرگومانهای تابع انجام میشود.
sum = Calculator.add(1, 2)
# => 3
میتوان بهجای def از کلیدواژهی defp برای تعریف یک تابع خصوصی استفاده کرد. توابع خصوصی فقط از داخل همان ماژولی که آنها را تعریف کرده است قابل استفادهاند.
هنگام فراخوانی یک تابع در همان ماژولی که تعریف شده است، میتوان اسم ماژول را حذف کرد.
همچنین میتوانید توابع کوتاه را با نحوهی نگارش یکخطی بنویسید (به کاما , و دونقطه : در دو طرف کلیدواژهی do توجه کنید).
defmodule Calculator do
def subtract(x, y) do
private_subtract(x, y)
end
defp private_subtract(x, y), do: x - y
end
difference = Calculator.subtract(7, 2)
# => 5
difference = Calculator.private_subtract(7, 2)
# => ** (UndefinedFunctionError) function Calculator.private_subtract/2 is undefined or private
# Calculator.private_subtract(7, 2)
رایج است که توابع را با _آریتی_شان بنامیم. آریتی یک تابع، تعداد آرگومانهایی است که میپذیرد.
# add/3 because this function has three arguments, thus an arity of 3
def add(x, y, z) do
x + y + z
end
اسم ماژولها باید از PascalCase استفاده کند. اسم یک ماژول باید با یک حرف بزرگ A-Z شروع شود و میتواند شامل حروف a-zA-Z، اعداد 0-9 و زیرخط _ باشد.
اسم متغیرها و توابع باید از snake_case استفاده کند. اسم یک متغیر یا تابع باید با یک حرف کوچک a-z یا زیرخط _ شروع شود، میتواند شامل حروف a-zA-Z، اعداد 0-9 و زیرخط _ باشد و ممکن است با علامت سؤال ? یا علامت تعجب ! پایان یابد.
کتابخانهی استاندارد الیکسیر بسیار غنی است و مستندات خوبی دارد. مستندات آن بهصورت آنلاین در hexdocs.pm/elixir در دسترس است. این لینک را جایی ذخیره کنید؛ خیلی از آن استفاده خواهید کرد!
بیشتر انواع دادهی توکار ماژولی متناظر دارند که توابعی برای کار با آن نوع داده ارائه میدهد؛ برای نمونه، ماژول Integer برای اعداد صحیح، ماژول String برای رشتهها، ماژول List برای فهرستها و به همین ترتیب.
یک ماژول قابل توجه، ماژول Kernel است. این ماژول توانمندیهای پایهای را فراهم میکند که بقیهی کتابخانهی استاندارد بر پایهی آنها ساخته شده است؛ مواردی مانند عملگرهای حسابی، ماکروهای کنترل جریان و بسیاری موارد دیگر. توابع ماژول Kernel بهطور خودکار وارد میشوند، بنابراین میتوانید آنها را بدون پیشوند Kernel. به کار ببرید.
از توضیحات میتوان برای گذاشتن یادداشت برای سایر توسعهدهندگانی که کد منبع را میخوانند، استفاده کرد. توضیحات تکخطی در الیکسیر با # شروع میشوند.
در این تمرین میخواهید کدی بنویسید که به شما کمک کند از کتاب آشپزی محبوبتان یک لازانیای عالی بپزید.
پنج وظیفه دارید که همه به زمان صرفشده برای پخت لازانیا مربوط میشوند.
تابع Lasagna.expected_minutes_in_oven/0 را تعریف کنید که هیچ آرگومانی نمیگیرد و برمیگرداند که لازانیا باید چند دقیقه در فر بماند. طبق کتاب آشپزی، زمان مورد انتظار در فر بر حسب دقیقه ۴۰ است:
Lasagna.expected_minutes_in_oven()
# => 40
تابع Lasagna.remaining_minutes_in_oven/1 را تعریف کنید که تعداد دقایقی را که لازانیا تا این لحظه در فر بوده است به عنوان آرگومان میگیرد و بر اساس زمان مورد انتظار در فر بر حسب دقیقه از وظیفهی قبلی، برمیگرداند که لازانیا هنوز چند دقیقه باید در فر بماند.
Lasagna.remaining_minutes_in_oven(30)
# => 10
تابع Lasagna.preparation_time_in_minutes/1 را تعریف کنید که تعداد لایههایی را که به لازانیا اضافه کردهاید به عنوان آرگومان میگیرد و برمیگرداند که چند دقیقه صرف آمادهسازی لازانیا کردهاید، با این فرض که آمادهسازی هر لایه ۲ دقیقه طول میکشد.
Lasagna.preparation_time_in_minutes(2)
# => 4
تابع Lasagna.total_time_in_minutes/2 را تعریف کنید که دو آرگومان میگیرد: آرگومان اول تعداد لایههایی است که به لازانیا اضافه کردهاید و آرگومان دوم تعداد دقایقی است که لازانیا در فر بوده است. تابع باید برمیگرداند که در کل چند دقیقه روی پخت لازانیا کار کردهاید، که مجموع زمان آمادهسازی بر حسب دقیقه و زمان بر حسب دقیقهای است که لازانیا تا این لحظه در فر گذرانده است.
Lasagna.total_time_in_minutes(3, 20)
# => 26
تابع Lasagna.alarm/0 را تعریف کنید که هیچ آرگومانی نمیگیرد و پیامی برمیگرداند که نشان میدهد لازانیا آمادهی خوردن است.
Lasagna.alarm()
# => "Ding!"