Letölthető példaprogramok:
A szokványos "hello world" | Helloworld.bet |
Faktoriális számítása rekurzióval | Faktorialis.bet |
Szorzótábla a for ciklus használatával | Ciklus.bet |
Négyzetgyök számítása loop ciklussal | Negyzetgyok.bet |
Tömb elemeinek rendezése és a text használata | Quicksort.bet |
Referenciák használata | Referencia.bet |
Példa öröklődésre | Oroklodes.bet |
Többszörös öröklődés emulálása | Tobbszoros.bet |
Egy egyszerű verem | Stack.bet |
Randevú | Randi.bet |
Párhuzamosság - konkurencia | Konkurencia.bet |
Kivételkezelés | Exception.bet |
Dinamikus kötés bemutatása | Dinamikus.bet |
Külön interfész és implementáció | Stack.bet Stackbody.bet Stackuser.bet |
Lift szimulátor | lift.html |
Példaprogramok magyarázattal:
Eredmény:
a = 20, b = 15
f = 2.710000, g = 3.140000
r1.name = kis
r2.name = nadirigo
Magyarázat:
A példa azt mutatja, hogy a többi programozási nyelvben szereplő fogalmak, konstans, változó, eljárás, osztály stb. hogyan valósíthatóak meg mintával, vagyis hogy a mintafogalom mennyire általánosítása ezeknek.
Az első három sor nem BETA nyelven, hanem az ún. fragment-rendszer nyelvén íródott. Ennek a három sornak hasonló a funkciója, mint az #include <stdio.h> sornak C-ben. Az ezek után következő rész már végig, a (#-től a #)-ig BETÁ-ban van. Látszik, hogy egy BETA program egy minta, aminek a do része kerül végrehajtásra. A program speciális minta, mert csak deklarációs, és végrehajtási része van.
A példaprogramban szereplő swap minta a deklarációs részhez tartozik (a program-minta deklarációs részéhez). Ez a swap minta tulajdonképpen egy függvény, ami megcseréli a két argumentumát, úgy hogy nem használ fel erre parancsokat (vagyis nincsen do része a mintának). Ez azért tehető meg, mert BETA-ban a minta több értéket is visszaadhat. Ez a swap minta csak azért szerepel, hogy bevezesse a gswap mintát, ami ennek egy általánosítása. A gswap csak egy kicsit tér el a swap mintától, szerepel benne a type :< object; sor, és a két paramétere nem egész, hanem type típusú. A type :< object; azt jelenti, hogy a type egy virtuális attribútum, ami lehet az object minta, vagy annak részmintája. Az object minta eléréséről az ORIGIN kezdetű sor gondoskodik, az object minta minden mintának a implicit szupermintája, tehát itt a type attribútum tulajdonképpen tetszőleges minta lehet. Ez az egyik szép tulajdonsága a BETA-nak - amit a minta-fogalom bevezetésével nyert -, hogy egy minta tartalmazhat osztály-attribútumokat is. A gswap mintát szupermintaként használva, és a virtuális type attribútumot kiterjesztve egy iswap és egy fswap függvény-mintát példányosítunk a következő két sorban. Az integerobject és a realobject mintákat szintén az ORIGIN sor segítségével érjük el, ezek sem a nyelv alapszavai. Azért van ezekre szükség, mert nem lehet olyat írni, hogy type ::< integer, ugyanis az alaptípusok (integer, char, real, ...) nem minták - hatékonysági okok miatt). Ha megnézzük a program-minta do részét, láthatjuk, hogyan kell meghívni a swap-függvényeket:
A '->' operátort használja a BETA az értékadásra, és az eljárás-, ill. függvényhívásra is, vagyis ezzel adja át az enter listában szereplő objektumoknak a nyíl bal oldalán szereplő értékeket. Látszik, hogy nincs éles különbség az értékadás és a függvényhívás között.
Többszörös értékadás is lehetséges a BETA-ban, de ez nem szimultán értékadás: az
utasítás az
szekvenciának felel meg.
Az (5, 2, 'nadi') -> r1; utasítás nem értékadás, hanem (jelen esetben) függvényhívásként értelmezhető. Ha a rigo mintának nem lenne enter listája, akkor ugyanez az inicializáló hatás a (5, 2, 'nadi') -> (r1.size, r1.color, r1.name) többszörös értékadással érhető el.
A programban látható példa konstans megvalósítására:
Vagyis a konstans a BETA-ban egy olyan minta, aminek csak visszatérési értéke van.
Tekintsük a programban szereplő legbonyolultabb mintadeklarációt (BETA-ban a deklaráció és a definíció fogalmak keverhetőek - a dokumentáció keveri is -, mert a C-ben megszokott módon nem lehet deklarálni típusleírót (itt mintát), BETA-ban mindig a teljes definíciót meg kell adni.) - ez a rigo minta deklarációja. Eltekintve a minta enter és exit listájától, észrevehető, hogy ez tulajdonképpen egy osztály, ugyanis megvannak az adatattribútumok (size, color, name) és van metódusa is (show, ami ráadásul virtuális). Az enter lista csak a fent említett egyszerűbb inicializálás céljából szerepel. Az exit listának ebben az esetben nincs igazán jelentősége. Az r2 objektum deklarációjánál látható, hogy a virtuálisnak deklarált show metódus akár a példányosítás alkalmával is kiterjeszthető.
Eredmény:
10,20
100,200,300
100,200,300
Magyarázat:
A példában először egy két-, majd egy háromdimenziós pontot leíró mintadeklaráció szerepel. A Point mintának a show virtuális attribútuma - ezt a :< jelöli -, amit a ThreeDpoint minta kiterjeszt. Felmerülhet a kérdés, hogy egy mintát eddig is ki tudtunk terjeszteni, mindenféle virtuális segítség nélkül, miért van tehát szükség virtuális mintára?
A válasz a következő: mintát ki tudunk terjeszteni a belőle származtatott részmintában, de ez a kiterjesztés annyit jelent, hogy új deklarációkat, paramétereket, utasításokat adunk hozzá a már meglévőkhöz. Viszont a már meglévő attribútumokat nem tudjuk így módosítani. Erre való a virtuális minta-attribútum (adatattribútum, metódus, vagy osztály), így megadjuk a lehetőséget, hogy ezt az attribútumot a későbbi származatatás (részminta-képzés) során megváltoztassuk. Ez a megváltoztatás viszont csak kiterjesztés lehet (az fenti módon).
A példában szereplő show eljárást, ha a Point mintában nem virtuális eljárás-mintaként lenne deklarálva, akkor a ThreeDpoint mintában szereplő show eljárás egyszerűen eltakarná, és csak a z értékét írná ki a b.show (persze ha a Point.show nem virtuális, akkor a ThreeDpoint.show deklarációjában ::< helyett :, vagy :< kell, hogy álljon).
Eredmény:
ABAA
Magyarázat:
Ez a példa a BETA minta-változójának egy lehetséges felhasználását mutatja. BETA-ban lehet egy mintára implicit módon hivatkozni, egy változón keresztül. A programban szereplő Create függvény paraméterként egy mintát kap, ezt példányosítja, és a példányt aktivizálja.
Magyarázat:
Ez a példa arról szól, hogy a BETA semmiféle korlátozást nem ad egy minta valamely attribútumának elérésére. Megfelelő hivatkozással elérhető olyan adat, akár írás, akár olvasás céljából, aminek elérését hasonló szituációban más nyelvekben korlátozni lehet. BETA-ban, ha egy adott programkörnyezetben az X minta látható, és X1 az X mintának egy attribútuma, akkor X.X1 elérhető abban a pontban. A példában láthatjuk, hogy az A objektummal azonos blokkban, vele egy szinten deklarált B objektum kényelmesen meg tudja változtatni A-nak az A1 belső változóját. Az információ elrejtése az ún. fragment-rendszer segítségével valósítható meg. Az adatrejtés sikere azon múlik, hogy az X.X1 kifejezés szintaktikailag helyes, az X.X1.X11 viszont szintaktikai hibát eredményez. A módszer lényege az, hogy a privát részeket egy blokkal mélyebbre süllyesztjük, és így azok a mintán kívülről már elérhetetlenek lesznek (egyszerűen azért, mert legfeljebb egy pont szerepelhet a hivatkozásban.)
A minta sokoldalúságát a következő példán keresztül szemléltetjük:
Legyen két alosztály: worker és salesman
Magyarázat:
employee: ez egy osztályminta, ahol a name, birthday, dept és totalHours alkotják az adatmezőket, registerWork és computeSalary pedig a függvénymezőket (metódusokat).
registerWork: ez egy nem-virtuális eljárásminta, ami azt jelenti, hogy a tevékenységét teljes egészében megadtuk az employee bázisosztály részeként. Az enter kulcsszó után kell az eljárásminták bemenő paramétereit felsorolni, a do kulcsszó után pedig az utasításokat kell megadni.
computeSalary: ez viszont virtuális eljárásminta, mert csak egy része lett specifikálva az employee bázisosztályon belül. Egy mintát a neve után írt :< jelpárral jelezhetünk virtuálisnak. A példában ez a minta azért lett virtuális, mert a fizetés kiszámítását a dolgozó szerepétől függően kívántuk differenciálni.
Az exit rész után a kimenő paramétereket sorolhatjuk fel. (Az enter és az exit rész opcionális szerepet tölt be az eljárásminták esetén; lehet, hogy mindkettő jelen van, lehet, hogy csak az egyik, és lehet, hogy egyik sem.)
Virtuális minta esetén kötelező az inner kulcsszó megadása a do részben. Az inner azt jelzi, hogy arra a helyre a származtatott osztályban megadott konkrét kódot kell majd a fordítónak bemásolnia. Más szóval: egy bázisosztály virtuális mintájának konkrét jelentése a bázisosztály alosztályaiban (származtatott osztályaiban, almintáiban) adható meg pontosan (illetve terjeszthető ki).
worker és salesman: az employee osztályminta almintái (subpattern), vagyis őket származtattuk az employee-ból (közvetlen leszármazottak). A computeSalary virtuális minta konkrét jelentését is itt adjuk meg; a ::< jelcsoport jelzi azt, hogy kiterjesztjük az ősosztályban megadott virtuális mintát, vagyis az ősben szereplő innert a most (a do rész után) megadott utasításokra kell (gondolatban) kicserélni. A ::< jelcsoporttal azt jelezzük, hogy a további származtatás esetén még mindig tovább akarjuk terjeszteni az adott mintát. Ha nem ez a szándékunk, akkor kell használni a :: jelpárt (a BETA terminológia final bindingnak nevezi ezt a jelpárt, kb. végső jelentés), ami azt jelzi, hogy az adott mintát már nem kívánjuk tovább építeni, vagyis az esetleges további származtatás esetén sem akarjuk a jelentését tovább bővíteni. Ebben az esetben természetesen az inner kulcsszót el kell hagyni a minta do részéből.
Még egy fontos megjegyzés az inner kulcsszóval kapcsolatban: ezzel a szerkezettel csak egy már meglévő rész továbbépítését végezhetjük el, vagyis az ősosztályokban megadott részfunkciókat nem lehet a virtuális mintákkal átdefiniálni (kicserélni)!
A worker és a salesman osztályon keresztül az öröklődésre is láthattunk példát.
A BETÁ-ban tehát az almintaképzés mechanizmusa a virtuális eljárásminták kiterjesztésével kombinálva jelenti az öröklődést, vagyis ily módon az alminták öröklik az ősmintáik (szupermintáik) tulajdonságait.
A fenti kódrészletekben tehát példát láthattunk osztály- és eljárásmintára, valamint almintára is. Az almintákban új attribútumokat vezethetünk be, kiterjeszthetjük a szupermintában (ősben) megadott virtuális minták definícióit, és megadhatunk új utasításokat is, amelyek a szuperminta utasításaival kombinálva hajtódnak végre; ezt támogatja az inner szerkezet.
Példa egymásba ágyazott mintákra:
(Eddig volt egy külső egymásba ágyazás az osztályok szintjén, és egy belső az eljárások szintjén. Most részobjektumok lesznek.)
Ekkor az o1.Print ki fogja írni a p1.name-t is, hasonlóan a o2.Print kiírja a p2.name-t is.