A nyelv számos beépített könyvtárat tartalmaz, melyek a következők:
Ez a rész egysoros leírásokat tartalmaz az Erlang kernel és stdlib függvény-könyvtáraiból, abból a célból, hogy ezt olvasgatva egyszerűen és gyorsan eldönthető legyen, hogy melyik függvényt kell jobban megnézni.
Általános OTP alkalmazás funkciók
Modul:config_change(Valtozott, Uj, Torolt) -> ok
Az alkalmazás konfigurációs beállításait lehet vele frissíteni.
Modul:prep_stop(Allapot) -> UjAllapot
Felkészíti az alkalmazást a leállásra.
Modul:start(StartTipus, StartParam) -> {ok, Pid} | {ok, Pid, Allapot} | {error, Kivalto}
Elindítja az alkalmazást.
Modul:start_phase(Fazis, StartTipus, FazisParam) -> {ok} | {error, Kivalto}
Az alkalmazás kiterjesztett indítása.
Modul:stop(Allapot)
Alkalmazás leállítása utáni műveletek (pl. fájlok bezárása, stb.).
get_all_env(Alkalmazas) -> Kornyezet
Visszaadja az alkalmazás konfigurációs beállításait.
get_all_key(Alkalmazas) -> {ok, Kulcsok} | undefined
Visszaadja az alkalmazást leíró kulcsokat.
get_application(Pid | Modul) -> {ok, Alkalmazas} | undefined
Visszaadja a folyamatot vagy modult tartalmazó alkalmazást.
get_env(Alkalmazas, Par) -> {ok, Ertek} | undefined
Visszaadja egy konfigurációs beállítás paraméterének értékét.
get_key(Alkalmazas, Kulcs) -> {ok, Ertek} | undefined
Visszaadja egy alkalmazást leíró kulcs értékét.
load(AlkLeiras, Elosztott) -> ok | {error, Kivalto}
Betölt egy alkalmazást.
loaded_application() -> ({Alkalmazas, Leiras, Vsn})
Visszaadja a már betöltött alkalmazásokat.
permit(Alkalmazas, Bool) -> ok | {error, Kivalto}
Megváltoztatja az alkalmazás jogosultságát egy adott node-on való futásra.
set_env(Alkalmazas, Par, Ertek, Timeout) -> ok
Beállítja egy konfigurációs paraméter értékét.
start(Alkalmazas, Tipus) -> ok | {error, Kivalto}
Betölt és elindít egy alkalmazást.
start_type() -> StartTipus | local | undefined
Visszaadja a folyamatban lévő alkalmazás-indulás típusát.
stop(Alkalmazas) -> ok | {error, Kivalto}
Megállít egy alkalmazást.
takeover(Alkalmazas, Tipus) -> ok | {error, Kivalto}
Átvesz egy elosztott alkalmazást.
unload(Alkalmazas) -> ok | {error, Kivalto}
Kitöröl egy betöltött alkalmazást.
unset_env(Alkalmazas, Par, Timeout) -> ok
Kitörli egy konfigurációs paraméter értékét.
which_applications(Timeout) -> ({Alkalmazas, Leiras, Vsn})
Visszaadja az éppen futó alkalmazásokat.
Base 64 kódolást és dekódolást valósít meg. Több információt erről itt találhatsz.
encode_to_string(Adat) -> Base64String
Kódolja az adatokat base 64 formátumba.
mime_decode_string(Base64String) -> Adat
Dekódolja a base 64 stringet adatokká.
BEAM fájl formátumot kezelő modul.
chunks(Beam, (DarabRef)) -> {ok, {Modul, (DarabAdat)}} | {error, beam_lib, Kivalto}
Beolvassa a kiválasztott darabokat (chunk) egy BEAM fileból vagy binárisból.
chunks(Beam, (DarabRef), (Opcio)) -> {ok, {Modul, (DarabAdat)}} | {error, beam_lib, Kivalto}
Beolvassa a kiválasztott darabokat (chunk) egy BEAM fileból vagy binárisból.
clear_crypto_key_fun() -> {ok, Eredmeny}
Kitörli a jelenlegi titkosítási kulcs függvényt.
cmp(Beam1, Beam2) -> ok | {error, beam_lib, Kivalto}
Összehasonlít két BEAM fájlt.
cmp_dirs(Kvtar1, Kvtar2) -> {Csak1, Csak2, Kulonbozo} | {error, beam_lib, Kivalto}
Összehasonlítja két külön könyvtárban lévő BEAM fájlokat.
crypto_key_fun(TitkosKulcsFgv) -> ok | {error, Kivalto}
Beállítja a jelenlegi titkosítási kulcs függvényt.
diff_dirs(Kvtar1, Kvtar2) -> ok | {error, beam_lib, Kivalto}
Összehasonlítja két külön könyvtárban lévő BEAM fájlokat.
format_error(Kivalto) -> String
Visszaad egy bővebb leírást a BEAM olvási hibáról.
info(Beam) -> ({item, Info}) | {error, beam_lib, Kivalto}
Információkat szolgáltat a BEAM fájlról.
md5(Beam) -> {ok, {Modul, Md5}} | {error, beam_lib, Kivalto}
Visszaadja a BEAM fájlban lévő modul verzióját.
strip(Beam1) -> {ok, {Modul, Beam2}} | {error, beam_lib, Kivalto}
Kitöröl olyan darabokat a BEAM fájlból, amire a betöltőnek nincs szüksége.
strip_files(Fileok) -> {ok, ({Modul, Beam2})} | {error, beam_lib, Kivalto}
Kitöröl olyan darabokat a BEAM fájlból, amire a betöltőnek nincs szüksége.
strip_release(Kvtar) -> {ok, ({Modul, Filenev})} | {error, beam_lib, Kivalto}
Kitöröl olyan darabokat BEAM fájlokból, amire a betöltőnek nincs szüksége.
version(Beam) -> {ok, {Modul, (Verzio)}} | {error, beam_lib, Kivalto}
Visszaadja a BEAM fájlban lévő modul verzióját.
Erlang shell parancssori függvényeit tartalmazza.
bt(Pid) -> void()
Egy folyamat (Erlang process) vermének back-trace-ét mutatja.
c(Fajl, Opciok) -> {ok, Modul} | error
Lefordít és betölt egy forráskódot tartalmazó fájlt.
cd(Kvtar) -> void()
Megváltoztatja a jelenlegi könyvtárat.
flush() -> void()
Minden shellnek küldött üzenetet kiír a képernyőre a bufferból.
help -> void()
Alapvető súgót jelenít meg.
i(X, Y, Z) -> void()
Információkat ad a <X.Y.Z> pid-jű folyamatról.
l(Modul) -> void()
Betölt vagy újratölt egy modult.
lc(Fajlok) -> ok
Lefordít mindent fájlt egy listában.
ls() -> void()
Kiírja a jelenlegi könyvtárban lévő fájlokat.
ls(Kvtar) -> void()
Kiírja egy könyvtárban lévő fájlokat.
m() -> void()
Megmondja, mely modulok vannak jelenleg betöltve.
m(Modul) -> void()
Infomációkat ad vissza egy modulról.
memory() -> ({Tipus, Meret})
Memória foglaltsági információkat ír ki.
memory((Tipus) -> ({Tipus, Meret})
Memória foglaltsági információkat ír ki.
nc(Fajl, Opciok) -> {ok, Module} | error
Lefordít és minden node-on betölt egy fájlt.
ni() -> void()
Információkat ír ki a rendszerről.
nl(Modul) -> void()
Betölt egy modult minden node-on.
nregs() -> void()
Bejegyzett folyamatokról információkat ír ki.
pid(X, Y, Z) -> pid()
X, Y, Z-t átalakítja pid-dé.
pwd() -> void()
Kiírja a jelenlegi könyvtár nevét.
q() -> void()
Kilépés. Az init:stop()-ot hívja meg.
xm(ModSpec) -> void()
Kereszthivatkozás ellenőrzést végez az adott modulon.
y(Fajl) -> YeccRet
LALR-1-es parser-t generál.
y(Fajl, Opciok) -> YeccRet
LALR-1-es parser-t generál.
Helyi és univerzális időt, hét napjait kezelő, dátumkonverziókat megvalósító modul.
date_to_gregorian_days(Ev, Ho, Nap) -> Napok
Kiszámítja a 0. évtől a megadott dátumig eltelt napok számát.
datetime_to_gregorian_seconds({Datum, Ido}) -> Masodperc
Kiszámítja a 0. évtől a megadott pillanatig eltelt másodpercek számát.
day_of_the_week(Ev, Ho, Nap) -> NapSzam
Visszaadja, hogy a hét melyik napjára esik az adott dátum.
gregorian_days_to_date(Napok) -> Datum
Visszaadja a dátumot a napok számából.
gregorian_seconds_to_datetime(Masodperc) -> {Datum, Ido}
Visszaadja az időpontot az eltelt másodpercek alapján.
is_leap_year(Ev) -> bool()
Visszaadja, hogy szökőév-e.
last_day_of_the_month(Ev, Ho) -> Nap
A megadott év megadott hónapjának utolsó napját adja vissza.
local_time() -> {Datum, Ido}
Kiszámítja a helyi időt.
local_time_to_universal_time_dst({Datum1, Ido1}) -> {Datum2, Ido2}
Helyi időt univerzális idővé alakít át.
now_to_datetime(Most) -> {Datum, Ido}
Átkonvertálja a mostot időpillanattá.
now_to_local_time(Most) -> {Datum, Ido}
Átkonvertálja a mostot helyi idővé.
seconds_to_daystime(Masodperc) -> {Napok, Ido}
A másodpercek számából kiszámítja az időt.
seconds_to_time(Masodperc) -> Time
A másodpercek számából kiszámítja az időt.
time_to_seconds(Ido) -> Masodperc
Kiszámítja az éjfél óta eltelt másodperceket egészen a megadott ideig.
universal_time() -> {Datum, Ido}
Visszaadja a jelenlegi univerzális időt.
universal_time_to_local_time({Datum1, Ido1}) -> {Datum2, Ido2}
Konvertálja az univerzális időt helyi idővé.
valid_date(Ev, Ho, Nap) -> bool()
Az Erlang nyelvben a gráfkezelés az OTP könyvtár digraph modulja által támogatott, így külön, harmadik féltől származó könyvtárcsomag nélkül lehet könnyedén, az Erlang nyelv koncepciójához jól illeszkedő módon kezelni a gráfokat. A digraph modul az irányított, címkézett gráfok kezelésére alkalmas, a modul a nevét a directed graph rövidítéseként kapta. Irányítatlan gráfokat úgy tudunk létrehozni, hogy minden élt mindkét irányba felveszünk azonos címkével. A párhuzamos élek és a hurokélek megengedettek a digraph modulban.
Bevezetőként tekintsük át azokat a fontos gráfelméleti fogalmakat, amelyeket a digraph modul is használ, és a továbbiakban hivatkozni fogunk rájuk.
Egy modulbeli gráf egy (V, E) párként reprezentálható. A V a gráfcsúcsok véges halmaza, az E pedig az (irányított) élek véges halmaza. Az E a V × V (a V Descartes-szorzata önmagával) részhalmazaként áll elő. A V halmaz lehet üres is (ekkor szükségszerűen az E is üres lesz), az így előállt egyedi gráfot üres gráfnak nevezzük. Mind a csúcsok, mind az élek Erlang termek által kerülnek reprezentálásra, ezeket a digraph modult felhasználó programozó adhatja meg. A csúcsokat, illetve az éleket azonosító termeknek értelemszerűen egy gráfon belül egyedinek kell lenniük.
A gráfok csúcsaihoz, illetve éleihez egyaránt további információk is csatolhatóak, ezeket címkéknek nevezzük, az így előállt gráfot pedig címkézett (irányított) gráfnak hívjuk. A címkék szintén Erlang termekként kerülnek reprezentálásra a modulban. Súlyozott gráfot ezáltal úgy hozhatunk létre, ha címkéknek számokat használunk.
Egy e = (v, w) élre azt mondjuk hogy a v csúcsból indul (ered), és a w csúcsba érkezik. Egy gráfcsúcs kimenő fokszámának (kifokának) a csúcsból kiinduló, bemenő fokszámának (befokának) pedig a csúcsba beérkező élek számát nevezzük. Ha létezik egy v gráfcsúcsból induló és w csúcsba érkező él, akkor azt mondhatjuk, hogy a w csúcs a v kimenő szomszédja, illetve a v gráfcsúcs pedig a w bemenő szomszédja. A v1 és vk gráfcsúcsok közötti P sétának egy (V, E) gráfban a V-beli v1, v2, ..., vk csúcsok nem üres, véges sorozatát nevezzük, ahol minden (vi, vi+1) rendezett párra létezik él E-ben (1 <= i < k). A P séta hossza ekkor k - 1. A P sétát egyszerűnek nevezzük, ha az összes érintett csúcs különböző, legfeljebb a két végcsúcs lehet megegyező. A P séta zárt, ha v1 = vk, egyébként a séta nyitott. A P sétát útnak hívjuk, ha egyszerű és nyitott. Körnek akkor mondjuk P sétát, ha egyszerű és zárt. Azt a speciális kört, amelynek hossza 1, hurokélnek hívjuk. Aszerint, hogy egy gráf tartalmaz-e kört, megkülönböztetünk ciklikus és aciklikus gráfokat.
Új gráfot a new függvénnyel tudunk létrehozni, ami az üres gráffal tér vissza.
Példa:
A gráf létrehozásakor egy paraméterrel megadhatjuk, hogy milyen típusú gráfot kívánunk létrehozni. A gráfunk egyrészt lehet ciklikus vagy aciklikus, az utóbbiban nem hozható létre kör. A gráf másrészt lehet védett vagy privát. A privát gráfhoz csak a kurrens processz férhet hozzá, a védett gráf ellenben a többi processz számára is olvasható. A gráf alapértelmezetten ciklikus és védett.
Példa:
A gráf típusára vonatkozó információk kinyerhetőek egy gráfból az info függvénnyel, amely kulcs-érték párok listájával tér vissza.
A digraph modul függvényei által lehetőség van csúcsok felvételére, módosítására és törlésére, illetve a csúcsoknak és címkéinek, kifokának, befokának, valamint még kimenő és bemenő szomszédjainak is a lekérdezésére.
Egy meglévő gráf csúcsai közé újat felvenni, illetőleg a meglévőket módosítani egyaránt az add_vertex függvénnyel lehetséges. A függvény első paraméterének a gráfot, a másodiknak a csúcsot, a harmadiknak pedig a címkéjét kell megadni. A függvény visszatérési értéke a létrehozott (vagy módosított) csúcs.
Példa:
Egy csúcs és a címkéje bármilyen term lehet, a csúcsokat praktikus megoldás lehet numerikusan számozni. A harmadik, címke paraméter elhagyható, ekkor a csúcs címkéje az üres lista ([]) lesz. A második paraméter is opcionális, ekkor a függvény egy új csúcsot vesz fel a gráfba a ['$v' | N ] term által reprezentálva, ahol N természetes szám.
Egy adott gráfból a vertex függvénnyel kérdezhetjük le a paraméterül átadott csúcs címkéjét. A visszatérési érték nem csak a címke lesz, hanem a csúcs és címke rendezett párja. (Nem létező csúcs esetén a visszatérési érték a logikai hamis.)
Példa:
Lehetőség van egy gráf összes csúcsának egy listában való lekérdezésére a vertices függvény által, azonban az eredmény listában a gráfcsúcsok rendezettségét tekintve semmilyen előfeltevéssel nem szabad élni.
A gráf csúcsainak számát a no_vertices függvény adja meg.
Irányított gráfokról lévén szó, a csúcsoknak megkülönböztetjük a kimenő és bemenő fokszámát. Ezeket az out_degree valamint az in_degree függvényekkel kérdezhetjük le. Az első paraméter a gráf, a második pedig a vizsgált gráfcsúcs lesz.
Példa:
A gráfcsúcs teljes fokszámát az előbbi példának megfelelően a befok és a kifok összegeként kaphatjuk meg irányított gráf esetében, irányítatlan gráfnál pedig a két érték mindig egyenlő.
A digraph modul arra is beépítetten lehetőséget nyújt, hogy egy csúcspont összes kimenő, valamint bemenő szomszédos csúcsát lekérdezzük. Ez az információ könnyen előállítható, hiszen az élek csúcsok rendezett párjaként kerülnek ábrázolásra. A gráf és a vizsgált csúcs, mint paraméterek átadásával az out_neighbours és az in_neighbours függvények térne vissza a kimenő, illetve a bemenő szomszédok listájával. Az eredmény listában a gráfcsúcsok rendezettségét tekintve semmilyen előfeltevéssel nem szabad élni.
Amennyiben egy gráfcsúcs összes szomszédjára kíváncsiak vagyunk egy irányított gráfban, akkor uniózzuk a kimenő és bemenő szomszédokat a duplikátumok törlése mellett, például az itt látható módon.
Irányítatlan gráfok esetében a bemenő és kimenő szomszédok természetesen megegyeznek, így erre nincs szükség.
Egy gráfcsúcs törlésekor a digraph modul automatikusan törli a csúcsból kiinduló, illetve a csúcsba beérkező éleket egyaránt, így a gráf semmiképp sem kerülhet inkonzisztens állapotba. Egy csúcsot a delete_vertex, csúcsok listáját pedig a delete_vertices függvénnyel távolíthatunk el a gráfból. A törlendő csúcsot, illetve csúcsokat a második paraméterként adhatjuk át, az első argumentum pedig a gráf.
Példa:
A digraph modul függvényei által lehetőség van élek felvételére, módosítására és törlésére, illetve az éleknek és címkéjüknek a lekérdezésére. Ezen alapműveletek mellett a könyvtár olyan összetettebb feladatokra is kész függvényeket nyújt, mint a két csúcs közötti út keresése, vagy egy adott csúcson áthaladó kör keresése. Ezeket a műveleteket ráadásul elvégezhetjük úgy is, hogy a leggyorsabban megtalálható vagy a legrövidebb utat, illetve kört keressük.
Egy meglévő gráf élei közé újat felvenni, illetőleg a meglévőket módosítani egyaránt az add_edge függvénnyel lehetséges. A függvény első paraméterének a gráfot, a másodiknak az élet, a harmadiknak és negyediknek az él kiindulási és beérkezési csúcsát, az ötödiknek pedig az él címkéjét kell megadni. A függvény visszatérési értéke a létrehozott (vagy módosított) él.
Példa:
Egy él és a címkéje bármilyen term lehet, de az éleket praktikus megoldás lehet numerikusan számozni. A második paraméter, az él megadása opcionális, ekkor a függvény egy új élt vesz fel a gráfba a ['$e' | N ] term által reprezentálva, ahol N természetes szám. Amennyiben az él termjének megadását elhagytuk, akkor az él címkéjét sem kötelező megadni. Ez esetben a címke az üres lista ([]) lesz.
Ha olyan élt vennénk fel egy gráfba, amelynek egyik megadott végpontja az adott gráfban nem létezik, vagy az él felvételével egy aciklikus gráfban kört hoznánk létre, akkor a függvény visszatérési értéke a hibát leíró tuple.
Egy adott gráfból az edge függvénnyel kérdezhetjük le a paraméterül átadott él címkéjét. A visszatérési érték nem csak a címke lesz, hanem az él, a két végcsúcs és a címke rendezett négyese.
Példa:
Lehetőség van egy gráf összes élének egy listában való lekérdezésére az edges függvény által. A függvény első paramétere mindenképpen a gráf lesz, de ha a második, opcionális paraméterként egy gráfcsúcsot megadunk, akkor csak azoknak az éleknek a listáját kapjuk vissza, amelyek a megadott csúcsból indulnak ki, vagy oda érkeznek be. Az eredmény listában egyik esetben sem szabad az élek rendezettségét tekintve bármilyen előfeltevéssel élni.
A gráf éleinek számát a no_edges függvény adja meg.
Két féle képpen kereshetünk egy gráfban utat két megadott csúcs között. A get_path függvény mélységi keresést folytat, és az első megtalált utat adja vissza. A get_short_path függvény ezzel szemben szélességi keresést folytat, és szintén az első megtalált úttal tér vissza. Az algoritmus működéséből fakadóan garantált, hogy ennél rövidebb hosszúságú út nincsen a két megadott csúcs között a gráfban.
Mindkét függvény három paramétert vár: a gráfot, a kiindulási csúcsot, valamint a cél csúcsot. A visszatérési értékük a megtalált út csúcsainak rendezett listája, vagy logikai hamis, ha nincsen út a két csúcs között.
Kört szintén két féle képpen, az úthoz igen hasonló módon kereshetünk egy gráfban egy megadott csúcsra illeszkedően. Mindkét függvény két paramétert vár: a gráfot, valamint azt a csúcsot, amit tartalmazni kell a körnek.
A get_cycle függvény előbb egy legalább 2 hosszúságú kört keres a gráfban, és az első megtalált csúcsinak rendezett listájával tér vissza. Ha nem talált ilyen kört, akkor megvizsgálja, hogy van egy hurokél a vizsgált csúcson és ha igen, akkor az adott csúccsal, mint egy elemű listával ([V]) tér vissza. A visszatérési érték egyéb esetben a logikai hamis.
A get_short_cycle ezzel szemben a megadott csúcson átvezető legrövidebb kört próbálja megkeresni - a hurokélt is beleértve. Ha nincsen a csúcson átvezető él, akkor a visszatérési érték a logikai hamis. Fontos, hogy ez a függvény a hurokélt, mint kételemű listát ([V, V]) adja vissza.
Egy gráf egy élét a delete_edge, élek listáját pedig a delete_edges függvénnyel távolíthatunk el a gráfból. Az törlendő élt, illetve éleket a második paraméterként adhatjuk át, az első argumentum pedig a gráf.
Példa:
A digraph modul lehetőséget kínál arra, hogy egy G = (V, E) gráfbeli két csúcs között az összes utat töröljük a del_path függvénnyel. A függvény első argumentuma a gráf, második és harmadik paramétere pedig a kiindulási és a cél csúcs. Megjegyzendő azonban a törlési művelet működése: az algoritmus kiválaszt egy tetszőleges v1, v2, ..., vk utat a kiindulási gráfcsúcstól a célig, és törli az összes (vi, vi+1) élt E-ből (1 <= i < k), a párhuzamosakat is. Ezt addig ismétli, amíg van út a két megadott csúcs között.
Egy gráf törlésére a használata után azért van szükség, mert a digraph modul a gráfok implementációját ETS táblákkal valósítja meg, amelyekre nincsen szemétgyűjtés. Ha nem történik meg egy gráfra a delete függvény meghívása, akkor az őt létrehozó processz végén törlődik.
A digraph_utils modul a digraph modul kiegészítéseként funkcionál: összetett, de gyakran használt és igen hasznos gráfalgoritmusok implementációját tartalmazza. A részletes leírásért lásd a hivatalos referencia oldalt.
Az Erlang nyelvben több lehetőségünk is van kulcs-érték párok kezelésére. Ezek közül kettőt ismertetünk részletesen.
A fejezethez készített mintaprogram megtalálható és letölthető a példaprogramok között.
A property lista adattípus egy két elemű tuple-ket tartalmazó lista. Az egyes tuple-k első eleme a kulcs, a második az adott kulcshoz tartozó érték. A kulcsok és az értékek is term típusúak. Ha a listában egy kulcs többször is előfordul, akkor az első előfordulásához tartozó értéket veszi figyelembe a property lista.
delete(Kulcs, Lista) -> Lista
Törli a paraméterként kapott listából az adott kulcs összes előfordulását.
get_all_values(Kulcs, Lista) -> [term()]
Ez a függvény visszaadja a kapott listában az adott kulcshoz létező összes értéket.
get_keys(Lista) -> [term()]
Ez a függvény visszaadja a kapott listában előforduló összes kulcsot.
get_value(Kulcs, Lista) -> term()
Ez a függvény megadja az adott kulcshoz tartozó értékek közül az elsőt.
is_defined(Kulcs, Lista) -> boolean()
Ezen függvény segítségével meghatározhatjuk, hogy az adott kulcs szerepel-e a listában. Ha benne van a listában, akkor a függvény ’true’ értékkel tér vissza. Ha nincs a listában a kulcs, akkor a függvény ’false’ értékkel tér vissza.
lookup(Kulcs, Lista) -> none | tuple()
Ezen függvény segítségével megkereshetünk egy kulcsot a listában. Ha létezik, akkor visszakapjuk az adott kulcs első előfordulásához tartozó kulcs-érték párt. Ha a kulcs nem létezik, akkor ’none’ értékkel tér vissza a függvény.
lookup_all(Kulcs, Lista) -> [tuple()]
Ezen függvény segítségével megkaphatjuk egy adott kulcs összes előfordulását a listában. Ha a kulcs nincs a listában, akkor a függvény egy üres listával tér vissza.
Az Erlang R17-es verziójának kiadásával bővült az adattípusok halmaza, valamint átdolgozták az egész nyelvet, hogy könnyebb legyen az új típusok beépítése. A map típust a record típus helyettesítésére hozták létre.
A map típus kulcs-érték párok asszociatív gyűjteménye. Más nyelvekben is megtalálható ez az adattípus:
Az Erlang nyelvben a kulcs és az érték típusának is term-nek kell lennie.
Map létrehozása:
Map = #{Kulcs1 => Érték1, Kulcs2 => Érték2, ...}
Használhatunk mintaillesztést is:
#{Kulcs1 := Minta1, Kulcs2 := Minta2, ...} = Map
Map frissítése:
ÚjMap = Map#{ Kulcs1 => Érték1, ... KulcsN := ÉrtékN, ...}
A frissítésre két operátor is rendelkezésünkre áll: „=>” és „:=”, de ezeknek nem ugyanaz a jelentése:
find(Kulcs, Map) -> {ok, Érték} | error
Megkeres egy kulcshoz tartozó értéket a map-ben. Ha a kulcs létezik, akkor visszaadja a hozzátartozó értéket. Ha a kulcs nem létezik, akkor hibával tér vissza a függvény.
from_list(Lista) -> Map
Ezzel a függvénnyel egy kulcs-érték párokat tartalmazó listából hozhatunk létre egy map-et. Ha egy kulcs többször is szerepel a listában, akkor a legkésőbb előforduló érték fog hozzá tartozni a map-ben.
get(Kulcs, Map) -> Érték
Ha az adott kulcs benne van a map-ben, akkor a függvény a hozzá tartozó értékkel tér vissza. Ha nincs benne, akkor kivétel generálódik.
is_key(Kulcs, Map) -> boolean()
Ezen függvény segítségével eldönthető, hogy az adott kulcsot tartalmazza-e a map. Ha igen, akkor ’true’ értékkel tér vissza. Ha nem, akkor pedig ’false’ lesz a függvény visszatérési értéke.
keys(Map) -> Kulcsok
Ez a függvény a mapben megtalálható összes kulcsot adja vissza egy lista formájában.
map(Fun, Map1) -> Map2
Ezzel a függvényel lehetőségünk van egy map-et létrehozni egy másik map-ből egy fun expression segítségével. A fun expression segítségével a régi map minden elemén végrehajtódik ugyanaz a művelet. A példában minden érték kétszerese fog szerepelni az új map-ban.
merge(Map1, Map2) -> Map3
Ezzel a függvényével egyesíthetünk két map-et. Ha van olyan kulcs, ami mindkét map-ben szerepel, akkor az ahhoz a kulcshoz tartozó érték a második paraméterbeli értéket kapja.
new() -> Map
Ezzel a függvénnyel egy új, üres map-et hozhatunk létre.
put(Kulcs, Érték, Map1) -> Map2
Ezzel a függvénnyel egy új kulcs-érték párt tehetünk a map-be. Ha a megadott kulcs már létezik, akkor a paraméterként kapott érték fog hozzátartozni. A függvény egy új map-pel fog visszatérni.
remove(Kulcs, Map1) -> Map2
Ezzel a függvénnyel eltávolíthatunk egy elemet a map-ből. Ha a megadott kulcs létezik akkor a visszatérési értékben már nem fog szerepelni a paraméterként megadott kulcsot tartalmazó pár.
size(Map) -> integer() >= 0
Ez a függvény a map elemeinek számát adja meg.
to_list(Map) -> [{Kulcs, Érték}]
Ez a függvény egy kulcs-érték párokból álló listát hoz létre egy map-ből.
update(Kulcs, Érték, Map1) -> Map2
Ha a paraméterként kapott kulcs benne van a map-ben, akkor a hozzá tartozó értéket lecseréli a paraméterként kapott értékre. Ha a kapott kulcs nem létezik, akkor kivétel generálódik.
values(Map) -> Értékek
Ez a függvény a paraméterként kapott map-ben található összes értéket adja vissza egy lista formájában.
without(Kulcsok, Map1) -> Map2
Ez a függvény az első paraméterként kapott listában szereplő kulcsokat kiveszi a második paraméterként kapott map-ből. Ha a listában olyan kulcs is szerepel, amely nem található meg a map-ben, akkor azt a függvény figyelmen kívül hagyja.
A témakörhöz egy példaprogramot találhatunk a Könyvtár linken.
A gen_event egy viselkedésminta modul, ami az eseménykezelést teszi lehetővé. Az Erlang OTP eseménykezelő modellje egy generikus eseményvezérlő (event manager) folyamatból, valamint tetszőleges számú eseménykezelőből (ezek dinamikusan adódnak, és törlődnek a vezérlőből) áll.
Minden eseménykezelő egy "callback" modulként kerül megvalósításra, amely egy előre definiált interfészt valósít meg. Minden eseményvezérlő, amit a gen_server modul használatával valósítunk meg, olyan függvényekre támaszkodik, amelyek kapcsolatban állnak az eseménykezelő modulok interfészével. A vezérlő és a kezelő függvényei közötti kapcsolata az alábbi:
Mivel minden eseménykezelő egyetlen "callback" modul, egy eseményvezérlőhöz több is tartozhat, és ezek futás közben dinamikusan hozzáadhatók és törölhetők. Következésképpen a gen_event sokkal kevésbé érzékeny a "callback" modulok hibáira, mint a többi viselkedésminta. Amennyiben egy hozzáadott eseménykezelő "callback" függvénye Reason eredményű hibával, vagy nem megfelelő értékű termmel tér vissza, a vezérlő tovább működik. Ilyen esetben csupán meghívja az érintett modul terminate/2 függvényét {error,{'EXIT',Reason}} vagy {error,Term} argumentummal, és ezzel törli az eseménykezelőt, anélkül, hogy ez bármilyen befolyással lenne a többi eseménykezelő működésére.
A gen_event folyamat hibernálható, amennyiben valamelyik eseménykezelő modul "callback" függvényének visszatérési értéke tartalmazza a 'hibernate' kulcsszót. Ez kifejezetten hasznos lehet, ha a szerver hosszú ideig tétlen maradhat. Ennek használata csak indokolt esetben javasolt, ugyanis egy hibernálás legalább két "szemétgyűjtést" eredményez (hibernáláskor, és rögtön az ébredés után), és nem kifizetődő minden esemény kezelésekor végigcsinálni.
Érdemes megjegyezni, hogy amennyiben több eseménykezelő is jelen van, az is elegendő, ha csak egyikük kéri a hibernálást, nem kell mindegyiküknek megtennie ezt.
start_link() -> Result
start_link(EventMgrName) -> Result
Típusai:
EventMgrName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Result = {ok,Pid} | {error,{already_started,Pid}}
Pid = pid()
Egy eseményvezérlő processzt készít a "supervisor tree" részeként. A függvényt a supervisor hívja közvetve, vagy közvetlenül, és ez biztosítja többek között azt, hogy a vezérlő hozzá fog kötődni.
Ha EventMgrName={local,Name}, az eseményvezérlő lokálisan regisztrált, Name névvel a register/2 használatával. Ha EventMgrName={global,GlobalName}, az eseményvezérlő globálisan került regisztrálásra GlobalName néven, a global:register_name/2használatával. Ha nincs név, a vezérlő regisztrálatlan. Ha EventMgrName={via,Module,ViaName}, a vezérlő a Module regisztrációs felületét használja a regisztrációjához, ezért a Module-nak exportálnia kell a register_name/2, unregister_name/1, whereis_name/1 and send/2 függvényeket, amelyeknek a globális megfelelőjükhöz hasonlóan kell viselkedniük. Következésképp a {via,global,GlobalName} helyes hivatkozás.
Amennyiben az eseméynvezérlő sikeresen létrejön, a függvény az {ok,Pid} eredménnyel tér vissza, amiben a Pid a vezérlő processz azonosítója. Ha már létezik EventMgrName nevű processz, a visszatérési érték {error,{already_started,Pid}} lesz, az érintett processz azonosítójával.
start() -> Result
start(EventMgrName) -> Result
Típusai:
EventMgrName = {local,Name} | {global,GlobalName} | {via,Module,ViaName}
Name = atom()
GlobalName = ViaName = term()
Result = {ok,Pid} | {error,{already_started,Pid}}
Pid = pid()
Egy supervisor nélküli, önálló eseményvezérlő processzt indít.
add_handler(EventMgrRef, Handler, Args) -> Result
Típusai:
EventMgr = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler = Module | {Module,Id}
Module = atom()
Id = term()
Args = term()
Result = ok | {'EXIT',Reason} | term()
Reason = term()
Egy új eseménykezelőt ad az EventMgrRef vezérlőhöz, ami meghívja a Module:init/1 függvényt, hogy inicializálja a kezelőt.
Az EventMgrRef értékei a következők lehetnek:
A "callback" modul neve Handler, vagy {Module,Id}, ahol Id bármilyen term lehet. Az utóbbi reprezentáció lehetővé teszi, hogy azonosítsunk különböző kezelőket, amelyek ugyanazt a "callback" modult használják.
Az Args egy tetszőleges term, ami a Module:init/1 függvény argumentuma lesz.
Ha a Module:init/1 megfelelő eredményt ad vissza jelezvén, hogy minden rendben ment, az eseményvezérlőhöz hozzáadódik a kezelő, és ez a függvény egy ok atommal tér vissza. Ha Module:init/1 hibásan fut le, melynek oka Reason, vagy {error,Reason} eredménnyel tér vissza, a kezelő elutasításra kerül, és a függvény visszatérési értéke {'EXIT',Reason} vagy {error,Reason} lesz.
add_sup_handler(EventMgrRef, Handler, Args) -> Result
Típusai:
EventMgr = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler = Module | {Module,Id}
Module = atom()
Id = term()
Args = term()
Result = ok | {'EXIT',Reason} | term()
Reason = term()
Az add_handler/3 függvényhez hasonlóan egy eseménykezelőt ad a vezérlőhöz, azonban a kezelő és a hívó processz kapcsolatát is felügyeli.
Ha a hívó processz később terminál Reason eredménnyel, a vezérlő törli a kezelőt, meghívva a Module:terminate/2 függvényt {stop,Reason} argumentummal. Ha a kezelő kerül törlésre, az eseményvezérlő egy {gen_event_EXIT,Handler,Reason} üzenetet küld a hívó processznek, ahol Reason értéke az alábbiak egyike:
notify(EventMgrRef, Event) -> ok
sync_notify(EventMgrRef, Event) -> ok
Típusai:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Event = term()
Egy esemény-értesítőt küld az EventMgrRef eseményvezérlő számára, ami ekkor az összes csatlakozott kezelő Module:handle_event/2 függvényét meghívja.
A notify aszinkron, és azonnal visszatér, amint az esemény-értesítő ki lett küldve. A sync_notify ezzel szemben szinkron hívás, abban az értelemben, hogy csak akkor tér vissza, ha az összes eseménykezelő feldolgozta az adott eseményt.
Az Event egy tetszőleges term, amit argumentumként kap meg a Module:handle_event/2.
call(EventMgrRef, Handler, Request) -> Result
call(EventMgrRef, Handler, Request, Timeout) -> Result
Típusai:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler = Module | {Module,Id}
Module = atom()
Id = term()
Request = term()
Timeout = int()>0 | infinity
Result = Reply | {error,Error}
Reply = term()
Error = bad_module | {'EXIT',Reason} | term()
Reason = term()
Szinkron hívást intéz az EventMgrRef eseményvezérlő Handler eseménykezelőjéhez, elküldve a kérést, majd várva a válasz érkezésére, vagy időtúllépésre. A vezérlő a Module:handle_call/2 függvényt hívja meg a kérés teljesítésére.
A Request egy testzőleges term, ami a Module:handle_call/2 argumentuma lesz.
A Timeout lehet egy pozitív egész szám, ami milliszekundumbanés határozza meg a válaszra várakozás időkorlátját, vagy lehet az infinity atom, ami határozatlan idejű várakozást eredményez. Az alapértelmezett érték 5000. Ha nincs válasz a megadott időn belül, a függvény hívás hibát eredményez.
A Reply eredmény a Module:handle_call/2 visszatérési értékében kerül definiálásra. Ha a megcélzott eseménykezelő nincs hozzáadva a vezérlőhöz a függvény a {error,bad_module} eredménnyel tér vissza. Ha a "callback" függvény Reason eredményű hibás futást produkál, vagy egy nem várt Term értékkel tér vissza, akkor ez a függvény a {error,{'EXIT',Reason}} vagy a {error,Term} válasszal tér vissza.
delete_handler(EventMgrRef, Handler, Args) -> Result
Típusai:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler = Module | {Module,Id}
Module = atom()
Id = term()
Args = term()
Result = term() | {error,module_not_found} | {'EXIT',Reason}
Reason = term()
Töröl egy eseménykezelőt az EventMgrRef eseményvezérlőből, ekkor a vezérlő meghívja a Module:terminate/2 függvényt, hogy a kezelő termináljon.
Az Args egy tetszőleges term, ami a Module:terminate/2 argumentuma lesz.
A visszatérési érték a Module:terminate/2 függvény eredménye. Ha a megcélzott kezelő nincs a vezérlőhöz adva, az eredmény: {error,module_not_found}. Ha a "callback" függvény Reason eredményű hibás futást produkál, az eredmény: {'EXIT',Reason}.
swap_handler(EventMgrRef, {Handler1,Args1}, {Handler2,Args2}) -> Result
Típusai:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler1 = Handler2 = Module | {Module,Id}
Module = atom()
Id = term()
Args1 = Args2 = term()
Result = ok | {error,Error}
Error = {'EXIT',Reason} | term()
Reason = term()
Lecserél egy régi eseménykezelőt egy újra az EventMgrRef eseményvezérlőben.
Első lépésként a régi eseménykezelő, Handler1 törlődik. A vezérlő meghívja a Module1:terminate(Args1, ...) függvényt, ahol a Module1 a Handler1 "callback" modulja, és begyűjt egy visszatérési értéket. Ezután a Module2:init({Args2,Term}) hívással, a Handler2 kerül hozzáadásra és inicializálásra, ahol a Module2 a Handler2 kezelő "callback" modulja, a Term pedig a Module1:terminate/2 visszatérési értéke. Ez lehetővé teszi a régi kezelőből az újba történő információküldést.
Ha a régi kezelő nincs a vezérlőhöz adva, az új akkor is hozzáadódik, de ebben az esetben Term=error. Ha Module1:terminate/2 hibát eredményez Reason-nal, akkor Term={'EXIT',Reason}. A régi kezelő abban az esetben is törlődik, ha a Module2:init/1 hibát eredményez.
Ha felügyelt kapcsolat volt a Hadnler1 és egy Pid processz között, akkor ezt felváltja egy Handler2 és Pid közötti felügyelt kapcsolat.
Ha a Module2:init/1 helyes értékkel tér vissza, az eredmény ok. Reason hiba, vagy nem várt értékű Term esetén a függvény a {error,{'EXIT',Reason}}, vagy {error,Term} eredményt adja.
swap_sup_handler(EventMgrRef, {Handler1,Args1}, {Handler2,Args2}) -> Result
Típusai:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler1 = Handler 2 = Module | {Module,Id}
Module = atom()
Id = term()
Args1 = Args2 = term()
Result = ok | {error,Error}
Error = {'EXIT',Reason} | term()
Reason = term()
A swap_handler/3-hoz hasonlóan lecserél egy eseménykezelőt az EventMgrRef eseményvezérlőben, de a Hadnler2 és a hívó processz közötti kapcsolat is felügyelet alá kerül.
which_handlers(EventMgrRef) -> [Handler]
Típusai:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Handler = Module | {Module,Id}
Module = atom()
Id = term()
Az EventMgrRef eseményvezérlő eseménykezelőinek listáját adja eredményül.
stop(EventMgrRef) -> ok
Típusai:
EventMgrRef = Name | {Name,Node} | {global,GlobalName} | {via,Module,ViaName} | pid()
Name = Node = atom()
GlobalName = ViaName = term()
Terminálja az EventMgrRef eseményvezérlőt, ám ezelőtt meghívódik az összes hozzáadott kezelő Module:terminate(stop,...) függvénye.
Részletesebb leírásért lásd az ERLANG hivatalos oldalát.