Miało być o testowaniu ale ja znów natrafiłem na zakręt i aż mnie korci by o tym napisać. Jenak dzisiejszy post jest spowodowany tworzeniem postu o testowaniu :) Gdyby nie testowanie nie doszedłbym do tego. Co tylko świadczy, że powinienem czytać pewnie od podstaw wszystkie tutoriale elixir, ale nie ważne. Podobno, lista słów kluczowych jest bardzo popularna w językach funkcyjnych, nie wiem tego nie mogę tego potwierdzić ani temu zaprzeczyć. Mogę zaś powiedzieć na czym polega i gdzie już z niej korzystaliście w elixir nawet nie wiedząc o tym.

Lista słów kluczowych to nic innego jak lista tuple dwu elementowego gdzie pierwszy element to atom a drugi to wartość:

{:one, 1}

Lista, więc:

[{:one, 1}, {:two, 2}]

Ze względu na to, że to jest tak popularne (podobno), elixir ma na to skrót, taki cukier składniowy:

[one: 1, two: 2]

To co wyróżnia taką listę to sposób dostępu do elementu. Na przykład możemy dostać się do wartości poprzez atom:

1 = list[:one]

Może się wydawać, że to taki słownik. Ale nim nie jest. Chociażby dlatego, że możemy posiadać więcej niż jedną parę o tym samym kluczu (o tym samym atom):

[a: 1] ++ [a: 2] ++ [a: 3] == [a: 1, a: 2, a: 3]

Operacje na liście słów kluczowych są liniowe, im dłuższa lista tym wolniej to będzie działało. Do tego w elixir istnieje cały dedykowany moduł do zabawy listą słów kluczowych Keyword, który umożliwia nam na przykład wyciągniecie jedynie wartości:

Keyword.values([a: 1, a: 2, a: 3]) = [1,2,3]

Do tego możemy usuwać czy też aktualizować elementy po kluczu itp. Ogólnie operacji jest sporo, ale nie dlatego w ogóle to opisuje. Robię to przez jedno z zastosować w elixir – parametry opcjonalne.

Dokładnie mówiąc, do ostatniego parametru metody możemy przekazać listę słów kluczowych, wygląda to tak jakbyśmy przekazywali wiele parametrów:

select [1,2,3], lessThen: 10, odd: :true

Wygląda to tak, jakby metoda select przyjmowała 3 parametry: listę, lessThen i odd. Gdzie w rzeczywistości przyjmuje ona dwa parametry zaś lessThen i odd jest zamieniane na listę słów kluczowych.

Definicja select może wyglądać więc tak:

defmodule Db do
    def select(list, filter) do
        wheres = Keyword.get_values(:where)
        # filter list
    end
end

Db.select [1,2,3], where: 3

Ok, słaby przykład. Ale rozumiecie mniej więcej jak to może działać.

A skoro rozumiecie to teraz popatrzmy na makro Kernel.defmodule/2 – tak, to jest makro:

defmodule Test do
    def t do
        1
    end
end

Który możemy też zapisać jako:

defmodule Test, do: def t, do: 1

Czy coś wam już świta? Zapiszę to inaczej:

defmodule(Test, [do: def(t, [do: 1])])

Dobra, ten przykład mógł być ciężki, zróbmy więc if:

if (1 == 1) do
    1
end

Można to zapisać jako:

if 1 == 1, do: 1

Co jest równoważne:

if(1==1, [do: 1])

Jak widać, blok do...end jest niczym innym jak kluczem w liście słów kluczowych!

Mi to trochę rozjaśniło w głowie i mam ciutkę mniej pytań niż miałem wcześniej. Teraz przynajmniej potrafię sobie odpowiedzieć na jakiej zasadzie działają parametry opcjonalne. Jeszcze pozostaje tylko kwestia tego jak to jest, że nawiasy klamrowe są dodawane i będę już szczęśliwy :) ktoś coś? :)