در الیکسیر با توابع بهعنوان شهروندان درجهیک رفتار میشود. یعنی:
توابع بینام، برخلاف توابع نامدار، مرجع ثابتی ندارند که در دسترسشان باشد؛ فقط زمانی در دسترساند که به یک متغیر نسبت داده شوند یا بلافاصله فراخوانی شوند.
ممکن است از توابع بینام برای این کارها استفاده کنیم:
توابع بینام با کلمهی رزروشدهی fn شروع میشوند، آرگومانها با نشانهی -> از بدنهی تابع جدا میشوند و با یک end پایان مییابند. مثل توابع نامدار، آخرین عبارت در تابع بهصورت ضمنی به تابع فراخوانکننده برگردانده میشود.
برای فراخوانی یک مرجع تابع، باید بین متغیر مرجع و فهرست آرگومانها از یک . استفاده کنید:
function_variable = fn param ->
param + 1
end
function_variable.(1)
# => 2
حتی میتوانید از نشانهگذاری کوتاه «capture» استفاده کنید تا این کار فشردهتر شود:
variable = &(&1 + 1)
variable.(1)
# => 2
الیکسیر توابع زیادی برای کار با بیتها دارد که در ماژول Bitwise قرار دارند.
band/2: AND بیتیbsl/2: شیفت چپ بیتیbsr/2: شیفت راست بیتیbxor/2: XOR بیتیbor/2: OR بیتیbnot/1: NOT بیتیدر ادامه مثالی از نحوهی استفاده از یک تابع بیتی را میبینید:
Bitwise.bsl(1, 3)
# => 8
همهی توابع بیتی فقط روی اعداد صحیح کار میکنند.
اگر از نسخهی ۱.۹ الیکسیر یا پایینتر استفاده میکنید، برای اینکه بتوانید از ماژول Bitwise استفاده کنید، باید در ابتدای تعریف ماژول، require Bitwise را فراخوانی کنید.
در این تمرین، وظیفهی شما نوشتن نرمافزار یک دستگاه رمزنگاری است که با انجام تبدیلها روی دادهها کار میکند. شما به روشی نیاز دارید که با آن بتوانید با ترکیب توابع سادهتر، توابع پیچیده را بهصورت انعطافپذیر بسازید.
برای هر وظیفه، یک «تابع بینام» برگردانید که بتوان آن را از «حوزهی فراخوانی» فراخوانی کرد.
همهی توابع باید آرگومانهایی از نوع عدد صحیح بگیرند. اعداد صحیح برای انجام عملیات بیتی در Elixir هم مناسباند.
تابع Secrets.secret_add/1 را پیادهسازی کنید. این تابع باید تابعی برگرداند که یک آرگومان میگیرد و آرگومانِ دادهشده به secret_add را به آن اضافه میکند.
adder = Secrets.secret_add(3)
adder.(2)
# => 5
تابع Secrets.secret_subtract/1 را پیادهسازی کنید. این تابع باید تابعی برگرداند که یک آرگومان میگیرد و مقدار محرمانهی دادهشده به secret_subtract را از آن آرگومان کم میکند.
subtractor = Secrets.secret_subtract(2)
subtractor.(3)
# => 1
تابع Secrets.secret_multiply/1 را پیادهسازی کنید. این تابع باید تابعی برگرداند که یک آرگومان میگیرد و آن را در مقدار محرمانهی دادهشده به secret_multiply ضرب میکند.
multiplier = Secrets.secret_multiply(7)
multiplier.(3)
# => 21
تابع Secrets.secret_divide/1 را پیادهسازی کنید. این تابع باید تابعی برگرداند که یک آرگومان میگیرد و آن را بر مقدار محرمانهی دادهشده به secret_divide تقسیم میکند.
divider = Secrets.secret_divide(3)
divider.(32)
# => 10
از تقسیم صحیح استفاده کنید تا خروجی با ورودی موردانتظار سایر توابع سازگار باشد.
and بسازیدتابع Secrets.secret_and/1 را پیادهسازی کنید. این تابع باید تابعی برگرداند که یک آرگومان میگیرد و یک عملیات بیتی and را روی آن و مقدار محرمانهی دادهشده به secret_and انجام میدهد.
ander = Secrets.secret_and(1)
ander.(2)
# => 0
xor بسازیدتابع Secrets.secret_xor/1 را پیادهسازی کنید. این تابع باید تابعی برگرداند که یک آرگومان میگیرد و یک عملیات بیتی xor را روی آن و مقدار محرمانهی دادهشده به secret_xor انجام میدهد.
xorer = Secrets.secret_xor(1)
xorer.(3)
# => 2
تابع Secrets.secret_combine/2 را پیادهسازی کنید. این تابع باید تابعی برگرداند که یک آرگومان میگیرد و دو تابعِ دادهشده به secret_combine را به ترتیب روی آن اعمال میکند.
add_one = Secrets.secret_add(1)
multiply_by_2 = Secrets.secret_multiply(2)
combined = Secrets.secret_combine(add_one, multiply_by_2)
combined.(3)
# => 8