İksir - Makrolar
Makrolar, Elixir'in en gelişmiş ve güçlü özelliklerinden biridir. Herhangi bir dilin tüm gelişmiş özelliklerinde olduğu gibi, makrolar idareli kullanılmalıdır. Derleme zamanında güçlü kod dönüşümleri gerçekleştirmeyi mümkün kılarlar. Şimdi makroların ne olduğunu ve bunların nasıl kullanılacağını kısaca anlayacağız.
Alıntı
Makrolar hakkında konuşmaya başlamadan önce, önce Elixir'in iç bileşenlerine bakalım. Elixir programı kendi veri yapılarıyla temsil edilebilir. Bir Elixir programının yapı taşı, üç unsuru olan bir gruptur. Örneğin, fonksiyon çağrısı sum (1, 2, 3) dahili olarak şu şekilde temsil edilir:
{:sum, [], [1, 2, 3]}
İlk öğe işlev adı, ikincisi meta verileri içeren bir anahtar sözcük listesi ve üçüncüsü bağımsız değişkenler listesidir. Aşağıdakileri yazarsanız, bunu iex shell'de çıktı olarak alabilirsiniz -
quote do: sum(1, 2, 3)
Operatörler de bu tür tuple olarak temsil edilir. Değişkenler, son elemanın bir liste yerine bir atom olması dışında, bu tür üçlüler kullanılarak da temsil edilir. Daha karmaşık ifadelerden alıntı yaparken, kodun genellikle bir ağaca benzeyen bir yapıda iç içe geçmiş bu tür tuplelar içinde temsil edildiğini görebiliriz. Birçok dil, bu tür temsilleri birAbstract Syntax Tree (AST). Elixir bu alıntılanmış ifadeleri çağırır.
Alıntıyı kaldır
Artık kodumuzun iç yapısını alabildiğimize göre, onu nasıl değiştirebiliriz? Yeni kod veya değerler enjekte etmek için kullanırızunquote. Bir ifadeyi alıntı yaptığımızda değerlendirilecek ve AST'ye enjekte edilecektir. Kavramı anlamak için bir örnek (iex shell'de) ele alalım -
num = 25
quote do: sum(15, num)
quote do: sum(15, unquote(num))
Yukarıdaki program çalıştırıldığında, aşağıdaki sonucu verir -
{:sum, [], [15, {:num, [], Elixir}]}
{:sum, [], [15, 25]}
Alıntı ifadesi örneğinde, num otomatik olarak 25 ile değiştirilmemiştir. AST'yi değiştirmek istiyorsak bu değişkeni alıntı yapmamız gerekir.
Makrolar
Artık alıntı ve alıntıya aşina olduğumuza göre Elixir'de makro programlamayı inceleyebiliriz.
En basit terimlerle makrolar, uygulama kodumuza eklenecek alıntılanmış bir ifade döndürmek için tasarlanmış özel işlevlerdir. Makronun bir işlev olarak adlandırılmak yerine, alıntılanan ifadeyle değiştirildiğini hayal edin. Makrolarla Elixir'i genişletmek ve uygulamalarımıza dinamik olarak kod eklemek için gereken her şeye sahibiz
Makro olmadıkça uygulayalım. Makroyu kullanarak tanımlayarak başlayacağız.defmacromakro. Makromuzun alıntılanmış bir ifade döndürmesi gerektiğini unutmayın.
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"
Yukarıdaki program çalıştırıldığında, aşağıdaki sonucu verir -
False expression
Burada olan şey, kodumuzun, never makrosu tarafından döndürülen alıntılanan kodla değiştirilmesidir . İfadeyi mevcut bağlamda değerlendirmek için alıntıdan çıkardık ve ayrıca kendi bağlamında yürütmek için do bloğundan alıntı yaptık. Bu örnek bize iksirdeki makroları kullanarak metaprogramlamayı gösteriyor.
Makrolar çok daha karmaşık görevlerde kullanılabilir, ancak idareli kullanılmalıdır. Bunun nedeni, genel olarak meta programlamanın kötü bir uygulama olarak görülmesi ve yalnızca gerekli olduğunda kullanılması gerektiğidir.