makrók haxe

Minden írásbeli értéknek felel Haxe 2 és majdnem igaz Haxe 3. De a munka minden változtatás nélkül csak akkor lesz a 2.. Aki alkalmazkodik a példákat a harmadik, és megosztani másokkal, lesz egy csomó ekspiriensa. Csak írásban nem állítja, hogy a végső igazság, és tartalmazhatnak hibákat.

Tehát mi valójában egy makró Haxe? Nem fogod elhinni, de a makrók szokásos funkciókat. Nos, nem egészen hétköznapi, de semmi rejtett, míg Haxe kódot őket nem. A fő előnye makrók - ez az, amit ők, amellett, hogy a standard könyvtár is rendelkezésre állnak az összes csomagot és osztályok neko haxe.macro és makrókkal hivatkoztak fordításkor helyett futásidőben és visszaút Haxe kódot és akkor lefut a szakaszában a program végrehajtását. Neko hozzáférést biztosít a fájlrendszer, és általában az egész rendszert, és haxe.macro osztályok lehetővé teszik. Igen, ezek mind lehetővé teszik, hogy: új osztályok, módosíthatja a meglévő struktúrát, hogy megkapja teljes részletességgel minden típusú, enum-ah, stb általában teljes hozzáférést. A lényeg, hogy pontosan tudja, mire van szüksége. Mindez makrók annyira érdekes számunkra. De ne sokat késleltetni, és nézd meg egy példát, hogy lesz tárolva a lefordított alkalmazás, és megjelennek a projekt készítés dátumát (nincs harmadik fél segédprogramok, mint a probléma megoldódott elég nehéz, majd jön a támogatás egy makró):

import haxe. makró. Context;
import haxe. makró. expr;

@: Macro statikus public function getBuildDate # 40; # 41; : Expr # 123;
var d = Date. most # 40; # 41; ;
visszatér kontextusban. makeExpr # 40; d. toString # 40; # 41;. Kontextusban. currentPos # 40; # 41; # 41; ;
# 125;
# 125;

Funkció getBuildDate mi makró. Azonnal hívja fel a figyelmet, hogy a meta tag @: makro elején a funkció - a fémjelzi azt mondja, hogy a fordító, hogy szükséges elvégezni ezt a funkciót fordításkor! A függvény típusát expr róla egy kicsit később. Tovább a módszer létrehoz egy normális getBuildDate időpontja az aktuális dátum, ami lefordítva a húr, és eljuttatja a „mágikus” Context.makeExpr és még kevésbé intuitív módszert Context.currentPos. És itt meg kell, hogy visszatérjen a Expr típusú, könnyű megtalálni a definíció a kód modult haxe.macro.Expr

typedef Expr = # 123;
var expr. ExprDef;
var pos. helyzetben;
# 125;

Expr - egy egyszerű szerkezetű, két mező: expr - bármilyen expressziós megengedhető Haxe, de nem a szokásos formában, de a mért értékek egyike ExprDef ENUM-egy (felsorolás típusú), például EFunction, evar, ENew, EConst, eSegélyhívó, EContinue , EReturn stb És pos - egy mutatót arra a helyre, ahol a fájl található a kifejezést. Valójában pos kiszámításához szükséges nem olyan gyakran, és elkezd emlékezni, hogy a helyén helyettesítő Context.currentPos (). Itt Pozíció típusa:

typedef Position = # 123;
var fájlt. string;
var min. int;
var max. int;
# 125;

Most, hogy Expr megszűnt a rejtély, vissza Context.makeExpr módszer. A cím egyértelmű, hogy csinál valamit, és itt is jobb, mint mondják, egy kép amit ő csinál:

Vissza a Expr struktúra leírása és győződjön meg arról, hogy valóban expr, amely egy karakterlánc konstans Econst (CString ()) a projekt készítés dátumát és található Main.hx 8 sorban, és elfoglalják a 8-20 karakter, és ez nagyon fontos! Vessen egy pillantást a 8-ik sorban az első példa a makró, azt mondja:

nyom # 40; getBuildDate # 40; # 41; # 41; ;

Ez történt: láttad, és remélem, hogy megértsék a saját, talán az első, de nem az utolsó makrót. Bár biztos vagyok benne, hogy volt egy kérdés: „Milyen mágikus #ha makro, mielőtt a fő funkciója?”. A lényeg az, hogy a makró funkció nagyban befolyásolja a viselkedését az osztály, amelyben meghatározott, és az import elérhető makrófüggvények gyakran megengedhetetlen többi kódot, és ez volt kibújik így illik, hogy mindent egy modult. De a tanácsom (és valóban így van helyesen): makrókat egy külön kijelölt osztályok nélkül összekeverjük őket a többi kódot. Akkor fogom tenni csak annyira, de a „vegyes” opciót, nem tudtam segíteni, de show.

Bevallom, ebben a cikkben akartam írni egy egész rakás makró, hogy vonzzák a lehető legtöbb ember, de megértjük, hogy a tudás nagyon kicsi, és nem valami jó túl korán. De bonyolítja az első makro - itt az ideje!

A feladat tűztünk ki magunk elé, nem a legegyszerűbb, és még egy kicsit bonyolult. makeExpr nem fogunk segíteni, tudja, hogy csak az alap és felsorolt ​​típusok (int, float, string, Bool, Array és névtelen objektumok tagjai ilyen típusú), itt az ideje, hogy forduljon a Context.parse módszer. Nézd, mit hoztam:

@: Macro statikus public function getBuildDate2 # 40; # 41; : Expr # 123;
var d = Date. most # 40; # 41; ;
visszatér kontextusban. elemez # 40; "Date.fromString („" + d. ToString # 40; # 41; + "„)". Kontextusban. currentPos # 40; # 41; # 41; ;
# 125;

Úgy látszik, hogy az első paraméter Context.parse vett tartalmazó karakterlánc Haxe kódot, de az eredmények arra utalnak, hogy már meg magad, csak mondom, hogy csináltam:

var date = getBuildDate2 # 40; # 41; ;
nyom # 40; dátum # 41; ;
nyom # 40; Típusát. typeof # 40; dátum # 41; # 41; ;

Context.parse - igen jól alkalmazható módszer az elemzési húrok tartalmazó Haxe kódot, például egy külső fájl vagy önszerveződő vonalak, mint a fenti példában. Van egy másik trükkös feladat, amelyet meg lehet oldani csak a segítségével ezt a módszert, és az ő elmondom, hogyan. De az igazat megvallva, nem szeretem elemzési és próbálja használni, csak ha feltétlenül szükséges, ha csak azért, mert az átvitt húrok tartalmazhatnak mondattani vagy logikai hibák, és az extra elemzés időigényes. Majd én megmutatom, hogyan mi probléma lehet adagolni értelmezni.

Annak érdekében, hogy „megszabaduljon” a Context.parse, igen, és megmutatni az erejét a makró, írja mindegy, de más és bonyolultabb :). De először, vissza a ExprDef szerkezet, mint mondtam, ez írja le olyan kifejezést Haxe, és így képes lesz arra, hogy leírjuk és a Date.fromString (). „De hogyan kell csinálni” - akkor meg fogja kérdezni, és bevallom őszintén, nem tudom. Nem, nos, néhány ExpDef tudom, a többi megtalálható a dokumentációban, de megmutatja a legegyszerűbb módszer, hogy megtanulják, hogyan kell rögzíteni a kívánt kifejezést. Egészen egyszerűen, hozunk létre itt van egy módszer:

@: Macro statikus funkció teszt # 40; e: Expr # 41; # 123;
nyom # 40; e # 41; ;
vissza az e;
# 125;

és hívja, átadva neki a jogot, hogy minket, mondván:

@: Macro statikus public function getBuildDate3 # 40; # 41; : Expr # 123;
var d = Date. most # 40; # 41; ;
var p = Context. currentPos # 40; # 41; ;
visszatérés # 123; expr: eCall # 40;
# 123; expr: EField # 40;
# 123; expr: EConst # 40; CIdent # 40; "Date" # 41; # 41;. pos: p # 125; .
"FromString" # 41; .
pos: p # 125; .
# 91; # 123; expr: EConst # 40; CString # 40; d. toString # 40; # 41; # 41; # 41;. pos: p # 125; # 93; # 41; .
pos: p # 125; ;
# 125;

Nos, azt mondtam, hogy mi lesz, hogy nehezebb, így tettünk. Nem fogom meggyőzni, hogy így helyes, vagy valami más, azt csak azt mondják, hogy a következő lesz egy másik lehetőség sokkal egyszerűbb, mint ezt, és ha még nem vadásznak, hogy megértsük, hogy itt, és amint megy, de ne felejtsük el, hogy az expr ExprDef, és még mindig meg kell dolgozni, ha kap, hogy a komplex makrók és a rendes feldolgozási és makeExpr akkor nem fog segíteni ott. Fontos, hogy ne félj, hogy nézd vissza gyakran, ahogy összegyűjti Haxe kifejezést (vizsgálati módszer fent), és minden, amit kap. És ne legyen lusta, hogy gondosan vizsgálja meg a teljes vonalon a recirkulációs arány legalább egy egyszerű példát.

Emlékezz, ahol elkezdtük: van egy szöveg egy időpontot, és azt akarjuk, hogy átadja azt az eljárást, amely e elemezni és visszaút dátumát. Ie Ideális esetben szeretnék venni, és küldje visszatérő Date.fromString (d.toString ()); és fogjuk ezt megtenni, vagy majdnem:

@: Macro statikus public function getBuildDate4 # 40; # 41; : Expr # 123;
var d = Date. most # 40; # 41; ;
var e = Context. makeExpr # 40; d. toString # 40; # 41;. Kontextusban. currentPos # 40; # 41; # 41; ;
visszaút makró dátuma. fromString # 40; $ e # 41; ;
# 125;

Véleményem kiderült nagyszerű! Az eredmény egybeesik getBuildDate4 getBuildDate3, de úgy tűnik, getBuildDate4 egyértelműen jobban néz ki. Vessen egy pillantást a változó értékét e az, amit az első visszatérő getBuildDate módszer -. Expression dátumot tartalmazó karakterlánc. A varázslat az utolsó sorban, miután egy return utasítást. Először azt látjuk, az üzemeltető makró, amely azt mondja a fordító, hogy mindaz, ami a szükséges lefordítani közvetlenül Expr. Ie ha írsz


ez ugyanaz, mint amit a levelet

# 123; expr: EConst # 40; CString # 40; "Foo" # 41; # 41;. pos: Context. currentPos # 40; # 41; # 125;

Elfogadom, jól átgondolt. És így ez a kifejezés, amely további értékeket kívülről, meg kell, hogy átadják a kulcsot $ az első, majd a fordító ezt a helyet tölti a kifejezés a változó, mindaddig, amíg (változó) is egyfajta expr ebben a példában $ e, továbbított eljárás fromString . így A horror több beágyazott enum-ok, felvettük az egész egy sorban: makro Date.fromString ($ e), 3 Haxe És lehet még könnyebb írni.

A Nicholas blog van egy nagyon jó példa arra, hogyan makró eldologiasodás egyszerűsített makrókódot, és nem tudok, hogy megmutassa:

@: Macro statikus függvény ismétlés # 40; e. Expr, en. expr # 41; # 123;
visszaút makró # 40; x 0 $ EN # 41; $ E;
# 125;

Ezt megelőzően, hogy egyszerűsítse a makrót írhatnánk legalább hét sornyi kódot! Elemzés, hogy mit csinál, és hogyan működik hagyjuk meg, remélem, most már nem lesz nehéz. Tip és a lehetőséget, hogy egyszerűsítse itt.

Ez az első alkalom, azt hiszem, eléggé, és felajánlotta neki, hogy. Összefoglalva, azt lehet mondani, most, hogy már megtanulták, hogy írjon egy egyszerű makró dolgozni Expr megtudtuk, néhány hasznos technikát Context osztályt, és valójában sokkal kicsit jobban megismerje a makro tárgyiasítást stb Amit nem tudom, hogyan lehet létrehozni saját osztályok és enum-ok, hogyan kell szerkeszteni az egész osztályt, hogy kiegészítse a módszerek vagy megváltoztatjuk a meglévő és még sok más. Remélem van ereje és felírom ezt az egészet.

Végül, hogy az elemzés a makrót a blog Nicholas kínálok még megpróbál mindent, hogy írjon egy makrót, majd mentse a fájlt értéket egy húr, és a következőképpen működik:

var str: string = MyMacros. getFileContent # 40; "Readme.txt" # 41; ;

Külön köszönet Alexander Kuzmenko. Alexander Khokhlov és SlavaRa segítséget írom ezt a cikket, felülvizsgálata, szerkesztés, és hasznos a kritika.

Kapcsolódó cikkek