Elixir - Makro
Makro adalah salah satu fitur Elixir yang paling canggih dan kuat. Seperti semua fitur lanjutan bahasa apa pun, makro harus digunakan dengan hemat. Mereka memungkinkan untuk melakukan transformasi kode yang kuat dalam waktu kompilasi. Sekarang kita akan memahami apa itu makro dan bagaimana menggunakannya secara singkat.
Kutipan
Sebelum kita mulai berbicara tentang makro, mari kita lihat internal Elixir. Program Elixir dapat diwakili oleh struktur datanya sendiri. Blok bangunan program Elixir adalah tupel dengan tiga elemen. Misalnya, panggilan fungsi sum (1, 2, 3) direpresentasikan secara internal sebagai -
{:sum, [], [1, 2, 3]}
Elemen pertama adalah nama fungsi, yang kedua adalah daftar kata kunci yang berisi metadata dan yang ketiga adalah daftar argumen. Anda bisa mendapatkan ini sebagai output di shell iex jika Anda menulis yang berikut -
quote do: sum(1, 2, 3)
Operator juga direpresentasikan sebagai tupel tersebut. Variabel juga direpresentasikan menggunakan triplet semacam itu, kecuali elemen terakhirnya adalah atom, bukan daftar. Saat mengutip ekspresi yang lebih kompleks, kita dapat melihat bahwa kode tersebut direpresentasikan dalam tupel semacam itu, yang sering bertumpuk di dalam satu sama lain dalam struktur yang menyerupai pohon. Banyak bahasa akan menyebut representasi seperti itu sebagaiAbstract Syntax Tree (AST). Elixir menyebut ekspresi dikutip ini.
Batalkan kutipan
Sekarang setelah kita dapat mengambil struktur internal dari kode kita, bagaimana kita memodifikasinya? Untuk memasukkan kode atau nilai baru, kami menggunakanunquote. Saat kami menghapus kutipan, ekspresi itu akan dievaluasi dan dimasukkan ke dalam AST. Mari kita pertimbangkan contoh (dalam shell iex) untuk memahami konsep -
num = 25
quote do: sum(15, num)
quote do: sum(15, unquote(num))
Ketika program di atas dijalankan, menghasilkan hasil sebagai berikut -
{:sum, [], [15, {:num, [], Elixir}]}
{:sum, [], [15, 25]}
Dalam contoh untuk ekspresi kutipan, itu tidak secara otomatis mengganti num dengan 25. Kita perlu menghapus variabel ini jika kita ingin memodifikasi AST.
Makro
Jadi sekarang kita sudah familiar dengan quote dan unquote, kita bisa menjelajahi metaprogramming di Elixir menggunakan macro.
Dalam istilah yang paling sederhana, makro adalah fungsi khusus yang dirancang untuk mengembalikan ekspresi yang dikutip yang akan dimasukkan ke dalam kode aplikasi kita. Bayangkan makro diganti dengan ekspresi yang dikutip daripada dipanggil seperti fungsi. Dengan makro kita memiliki semua yang diperlukan untuk memperluas Elixir dan secara dinamis menambahkan kode ke aplikasi kita
Mari kita terapkan kecuali sebagai makro. Kami akan mulai dengan mendefinisikan makro menggunakandefmacromakro. Ingatlah bahwa makro kita perlu mengembalikan ekspresi yang dikutip.
defmodule OurMacro do
defmacro unless(expr, do: block) do
quote do
if !unquote(expr), do: unquote(block)
end
end
end
require OurMacro
OurMacro.unless true, do: IO.puts "True Expression"
OurMacro.unless false, do: IO.puts "False expression"
Ketika program di atas dijalankan, menghasilkan hasil sebagai berikut -
False expression
Apa yang terjadi di sini adalah kode kami digantikan oleh kode kutipan yang dikembalikan oleh makro kecuali . Kami telah menghapus ekspresi untuk mengevaluasinya dalam konteks saat ini dan juga menghapus tanda kutip blok do untuk mengeksekusinya dalam konteksnya. Contoh ini menunjukkan kepada kita metaprogramming menggunakan makro di elixir.
Makro dapat digunakan dalam tugas yang jauh lebih kompleks tetapi harus digunakan dengan hemat. Ini karena metaprogramming secara umum dianggap sebagai praktik yang buruk dan sebaiknya digunakan hanya jika diperlukan.