╚esk² programovacφ jazyk Flex a modFlex
Flex je nov² programovacφ jazyk ΦeskΘ provenience, zalo₧en² na jazyku Ada, s d∙razem na vysokou spolehlivost a bezpeΦnost. Je to univerzßlnφ programovacφ jazyk, my se zde vÜak budeme zajφmat p°edevÜφm o webovΘ aplikace, kde Flex m∙₧e b²t pou₧it jako alternativa k PHP. V tomto Φlßnku budu demonstrovat filozofii Flexu na jednoduchΘ aplikaci.
Firma A&&L soft s. r. o. se ₧ivφ v²vojem elektronickΘho bankovnictvφ a Flex vznikl jaksi bokem, proto₧e ₧ßdn² z b∞₧n∞ pou₧φvan²ch jazyk∙ nevyhovoval jejφm pot°ebßm. Tφm, ₧e tento jazyk navrhli chlapci od bankovnφch systΘm∙, je z velkΘ Φßsti dßno, na co byl p°i nßvrhu kladen d∙raz - spolehlivost, bezpeΦnost a snadnou udr₧ovatelnost k≤du. Auto°i vÜak tvrdφ, ₧e nejde o jazyk pro ·zkΘ pou₧itφ, ale o jazyk univerzßlnφ.
Flex byl do znaΦnΘ mφry inspirovßn jazykem Ada. Adu vyvinulo na poΦßtku osmdesßt²ch let americkΘ ministerstvo obrany a pou₧φvß se v mission/safety-critical aplikacφch. V Ad∞ je nap°φklad °φdφcφ software k raketoplßnu. Poslednφ standard Ady je z roku 1995, je tedy jasnΘ, ₧e Ada v modernφch aplikacφch u₧ ztrßcφ dech, zatφmco Flex by m∞l poskytovat programßtor∙m vÜechno, co mß modernφ jazyk mφt. Flex podporuje "vÜechny stupn∞ abstrakce" a umo₧≥uje konzervativnφ strukturovanΘ programovßnφ, podpo°enΘ silnou typovou kontrolou, ale i plnohodnotnΘ OOP. Flex se tedy sna₧φ b²t progresivnφ i konzervativnφ zßrove≥. Neobsahuje ₧ßdnΘ nevyzkouÜenΘ postupy, vÜe, co v n∞m najdeme, znßme ji₧ odjinud. Nep°φjemn²m d∙sledkem tohoto p°φstupu je, ₧e se jazyk zaΦßteΦnφk∙m m∙₧e jevit jako komplikovan², aΦkoli je o dost jednoduÜÜφ ne₧ t°eba prßv∞ Ada.
Co je modFlex
U₧ z nßzvu je patrnΘ, o co jde - modFlex je modul populßrnφho HTTP serveru Apache, kter² umo₧≥uje pou₧φt Flex pro generovßnφ dynamickΘho webu. Pokud modFlex obdr₧φ po₧adavek na n∞jak² flexovsk² skript, p°elo₧φ ho, vyrobφ z n∞j knihovnu ve formßtu DLL, tu naΦte do pam∞ti a pou₧ije k obslou₧enφ po₧adavku. P°eklad samoz°ejm∞ neprobφhß p°i ka₧dΘm po₧adavku, ale jen po zm∞n∞ zdrojovΘho skriptu.
P°esto₧e tato architektura se spφÜe podobß architektu°e JavaServlet∙ (a jak dßle uvidφme, flexovskΘ skripty trochu p°ipomφnajφ JavaServlety), auto°i se zatφm nesna₧φ konkurovat webov²m °eÜenφm postaven²m na Jav∞. Flex je spφÜe konkurencφ pro PHP, coby bezpeΦn∞jÜφ alternativa k tomuto populßrnφmu nßstroji. Tomu odpovφdß i p°φtomnost nativnφho bindingu na knihovny PHP. JakΘkoli knihovnφ funkce, kterΘ jste zvyklφ pou₧φvat v PHP, m∙₧ete pou₧φvat i s modFlex. Samoz°ejmostφ je i snaha o konkurenci v cenovΘ oblasti - modFlex je pochopiteln∞ zdarma.
Vzhled skript∙
UrΦit∞ u₧ jste zv∞davφ na n∞jak² ten kousek zdrojovΘho k≤du. Samoz°ejm∞ by byl h°φch nezaΦφt n∞jak²m tφm "Ahoj sv∞te!", vypsan²m na obrazovku (do okna prohlφ₧eΦe):
with
mflib; -- Hlavnφ modul modFlexu zprost°edkovßvß spojenφ s vn∞jÜφm sv∞tem.
begin
modflex_request^.out_header.insert('Content-Type', 'text/plain; charset=UTF-8');
á
write_line('Ahoj, mnohovesmφre!');
á
modflex_request^.out_result := 200;
modflex_request^.out_result_info := 'OK';
end ahoj_svete;
Zde ho mßte. Podrobn∞jÜφ komentß°e si vyÜet°φme na komplikovan∞jÜφ k≤d. Zde se jen poÜle klientovi hlaviΦka obsahujφcφ formßt odpov∞di, p°idß se sama odpov∞∩ a celß akce se dokonΦφ nastavenφm statutu protokolu HTTP.
Jak vidφte, Flex mß pascalskou syntaxi (stejn∞ jako Ada). P°esto₧e v²sledkem p°ekladu bude DLL knihovna, k≤d je formßln∞ oznaΦen jako program. ╪et∞zce se vklßdajφ do jednoduch²ch apostrof∙, st°φÜka slou₧φ k dereferencovßnφ ukazatel∙, komentß°e se pφÜφ za dvojitou pomlΦku. Za zmφnku jeÜt∞ stojφ ono end ahoj_svete; ·pln∞ na konci û "pojmenovanΘ endy" jsou povinnΘ, proto₧e toto opat°enφ zlepÜuje orientaci v delÜφch programech.
D∙le₧itΘ je, ₧e modFlex akceptuje zdrojovΘ k≤dy jenom v k≤dovßnφ UTF-8. Vnit°n∞ jsou vÜechny °et∞zce v UNICODE. Skripty tedy m∙₧ete psßt v libovolnΘm textovΘm editoru, kter² toto k≤dovßnφ zvlßdß, i kdy₧ je lepÜφ pou₧φt n∞jak² modernφ editor, kter² zvlßdne i zv²razn∞nφ syntaxe. K dispozici je °ada integraΦnφch balφk∙, kterß se stßle rozÜi°uje. Bohu₧el v souΦasnosti jeÜt∞ neexistuje podpora pro oblφben² PSPad.
Ukßzka prßce s Flexem
Seznamovacφ skript mßme za sebou, tak₧e je Φas na rozsßhlejÜφ p°φklad. Tφm bude rafinovanß webovß aplikace, kterß vyd∞lφ dv∞ celß nezßpornß Φφsla a zobrazφ v²sledek. Komentß°∙ p°φmo v k≤du bude poskrovnu, zato budu komentovat ka₧d² ·sek k≤du v textu.
Aplikace se sklßdß z hlavnφho programu a jednoho modulu. Moduly ve Flexu vφce mΘn∞ odpovφdajφ jednotkßm (unit∙m) v Pascalu - a₧ na n∞kolik vylepÜenφ. Moduly se mohou hierarchicky vno°ovat do sebe a dokonce mohou b²t d∞d∞ny. P°i rozboru budeme postupovat stylem "shora dol∙", tak₧e te∩ hlavnφ program:
with
modulek,
mflib;á
var
stranka : c_stranka;
begin
modflex_request^.out_header.insert('Content-Type', 'text/html; charset=UTF-8');
stranka.vypis_telo;
stranka.vypis_dynamicky_obsah;
stranka.vypis_konec;
leave
modflex_request^.out_result := 200;
modflex_request^.out_result_info := 'OK';
end priklad;
Tento program mß jen o Üest °ßdek vφc, ne₧ ·vodnφ "Ahoj sv∞te!". Prvnφ zm∞nou je, ₧e tento program pou₧φvß krom∞ standardnφho modulu mflib
i modul modulek
, ve kterΘm budou "st°eva" naÜφ aplikace. Dßle deklarace instance stranka
t°φdy c_stranka
(je taktΘ₧ v modulu modulek
). Flex nepou₧φvß referenΦnφ objektov² model jako Java nebo Delphi, ale spφÜe systΘm z C++, tak₧e tato deklarace rovnou vytvo°φ instanci t°φdy. Poslednφ zm∞nou je sekce uvozenß klφΦov²m slovem leave
, kterΘ odpovφdß klφΦovΘmu slovu finally
z Javy - skript se pokusφ dokonΦit HTTP po₧adavek, i kdy₧ nastane neoÜet°enß v²jimka. Zde to vlastn∞ ani nenφ pot°eba, proto₧e odpov∞∩ "200 OK" je v²chozφ, obecn∞ se leave
sekce hodφ pro uvol≥ovßnφ zdroj∙, kterΘ musφ b²t uvoln∞ny i v p°φpad∞ chyby.
Te∩ p°iÜel Φas na popis modulu modulek
. Flex preferuje dvojstopΘ programovßnφ - moduly i t°φdy b²vajφ zpravidla rozd∞leny na ve°ejnou specifikaci a privßtnφ implementaci, ka₧dou Φßst ve zvlßÜtnφm souboru. OvÜem nenφ to nutnou podmφnkou, m∙₧ete slouΦit jak soubory, tak specifikaΦnφ a implementaΦnφ Φßst. V naÜφ aplikaci jsem modul i t°φdu rozd∞lil. Specifikace modulku
vypadß takto:
class public c_stranka =
static vypis_telo;
static vypis_dynamicky_obsah;
static vypis_konec;
end c_stranka;
end modulek;
Ve°ejnß specifikace modulu modulek
obsahuje jednu d∙le₧itou polo₧ku, a sice specifikaci t°φdy c_stranka
. Tato t°φda obsahuje t°i metody, kterΘ se budou starat o v²pis HTML k≤du do prohlφ₧eΦe. Metody zaΦφnajφ klφΦov²m slovem static
, kterΘ ale neznamenß, ₧e se jednß o statickΘ metody jak je znßme z jazyk∙ Java, C# nebo C++, ale ₧e tyto metody nelze v p°φpadn²ch potomcφch t°φdy c_stranka
p°edefinovat. Pokud bychom o mo₧nost p°edefinovßnφ stßli, byly by metody uvozeny klφΦov²m slovem virtual
a samotnΘho p°edefinovßnφ v p°φpadn²ch potomcφch bychom dosßhli p°es override
. SkuteΦnΘ statickΘ metody t°φdy se uvozujφ klφΦov²m slovem procedure
.
Nynφ se podφvßme na implementaci modulu modulek.
Jeho zaΦßtek vypadß takto:
with mflib,
standard,
standard.conversions;
type t_delitel = t_unsigned range 1..t_unsigned:last;
Nejprve je zde v²Φet pou₧φvan²ch modul∙, krom∞ tradiΦnφho mflib
obsahuje jeÜt∞ standard
, kter² definuje datovΘ typy pou₧φvanΘ ve standardnφch knihovnßch Flexu, a standard.conversions
pro p°evody z °et∞zce na Φφslo a naopak. Zde je nutno poznamenat, ₧e Flex neobsahuje ₧ßdnΘ p°eddefinovanΘ typy, poskytuje pouze prost°edky pro deklaraci typ∙. Jen tak pro zajφmavost, definice ÜestnßctibitovΘho znamΘnkovΘho Φφsla z modulu standard
vypadß nßsledovn∞:
Pro ·Φely ukßzkovΘ aplikace jsem takΘ nadefinoval jeden nov² typ, a to t_delitel
. Ve skuteΦnosti je to potomek typu t_unsigned
s omezen²m rozsahem hodnot. Takto se vyhneme nebezpeΦφ d∞lenφ nulou, proto₧e nulu do prom∞nnΘ typu t_delitel¡
prost∞ p°i°adit nebude mo₧nΘ.
Flex pou₧φvß takzvan² siln² typov² systΘm, tedy ·pln² opak p∙vodnφ filozofie PHP. Ve Flexu je ka₧dß prom∞nnß n∞jakΘho nem∞nnΘho typu. Prom∞nnΘ stejnΘho typu lze libovoln∞ p°i°azovat, prom∞nnΘ r∙zn²ch typ∙ mezi sebou automaticky p°i°azovat nelze. ZnamΘnkovΘ Φφslo do neznamΘnkovΘho prost∞ nep°i°adφte, tedy pokud nepou₧ijete explicitnφ p°etypovßnφ. Takovßto strategie se v∞tÜinou pozitivn∞ projevφ ve spolehlivosti vytvß°en²ch program∙. Prßce s typy je vid∞t v nßsledujφcφ procedu°e:
procedure dej_dynamicky_obsah(html_tag : t_char32str)
return t_char32str =
var
delenec : t_unsigned;
delitel : t_delitel;
podil : t_unsigned;
begin
delenec := string_to_unsigned(modflex_request^.get_vars.find('delenec'));
delitel := string_to_unsigned(modflex_request^.get_vars.find('delitel'));
podil := delenec div delitel;
result := '<' & html_tag & '>' & unsigned_to_string(podil) & '</' & html_tag & '>';
catch
when constraint_error do
result := 'Φφslo mimo povolen² rozsah';
when conversion_error do
result := 'nekorektnφ Φφslo';
when others do
result := 'nespecifikovanß chyba';
end dej_dynamicky_obsah;
Jednß se o b∞₧nou proceduru (nikoli o metodu), kterß p°ebφrß jeden parametr typu °et∞zec znak∙ a v²sledek vracφ tΘ₧ jako °et∞zec znak∙. Zajφmavostφ je, ₧e Flex mß univerzßlnφ °et∞zce - tedy nejen znakovΘ, klidn∞ m∙₧ete mφt °et∞zec cel²ch Φφsel. DalÜφ specialita je, ₧e Flex neznß klφΦovΘ slovo function
, hodnotu m∙₧e vrßtit i procedura nebo statickß Φi virtußlnφ metoda.
V tΘto konkrΘtnφ procedu°e jsou nejprve deklarovßny t°i prom∞nnΘ. V zadßnφ jsme se omezili na kladnß Φφsla, d∞litel je typu t_delitel
, co₧ nßm zaruΦuje, ₧e nikdy nebudeme d∞lit nulou. Prom∞nnΘ delenec
a delitel
se naplnφ z prom∞nn²ch, p°edan²ch v HTTP po₧adavku metodou GET. Pak se vypoΦφtß podφl, p°evede se na °et∞zec a obalφ se HTML elementem, kter² procedura dostala jako parametr. (VÜimn∞te si pou₧itφ ampersandu na mφst∞ operßtoru z°et∞zenφ.) Nßvratovß hodnota procedury se ulo₧φ do prom∞nnΘ result
.
Za poslednφm °ßdkem "°ßdnΘho" k≤du se nachßzφ sekce pro zotavenφ z chyb. KlφΦovΘ slovo catch
mß obdobn² v²znam jako v jazycφch Java nebo C++. K≤d za catch
se provede, pokud v °ßdnΘm k≤du procedury nastane v²jimka. Ta m∙₧e b²t vyvolßna nap°φklad p°i p°evodu °et∞zce na Φφslo. Zjistφme tedy typ v²jimky a podle toho upravφme nßvratovou hodnotu procedury.
VÜimn∞te si, ₧e tato procedura je velice robustnφ. Bu∩ korektn∞ provede to, co se od nφ oΦekßvß, nebo sluÜn∞ vrßtφ p°esn∞ diagnostikovanou chybu, co₧ v PHP Φasto nenφ mo₧nΘ bez slo₧itΘho testovßnφ parametr∙.
S hlavnφ Φßstφ ukßzkovΘ aplikace jsme hotovi, nynφ se vrßtφme ke t°φd∞ c_stranka
, jejφ₧ implementace je taktΘ₧ v implementaΦnφ Φßsti modulu modulek
:
class private c_stranka =
static vypis_telo =
begin
write_line('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">');
write_line('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="cs" lang="cs">');
write_line('<head><title>Priklad v modFlexu</title></head>');
write_line('<body>');
write_line(' <h1>DeliΦka</h1>');
write_line('<form action="priklad.src" method="get">');
write_line(' d∞lenec: <input type="text" name="delenec" />');
write_line(' d∞litel: <input type="text" name="delitel" />');
write_line(' <input type="submit" value="Vyd∞lit" />');
write_line('</form>');
end vypis_telo;
Uvedenß metoda jednoduÜe vypφÜe HTML k≤d, kter² modFlex odeÜle prohlφ₧eΦi. Na strßnce bude jednoduch² webov² formulß°, pro zadßnφ d∞lence a d∞litele. Druhß a t°etφ metoda a konec modulu je zde:
begin
if modflex_request^.get_vars.exist('delenec') and
modflex_request^.get_vars.exist('delitel')
then
write_line(dej_dynamicky_obsah('b'));
else
write_line('zadejte dv∞ kladnß celß Φφsla');
end if;
end vypis_dynamicky_obsah;
static vypis_konec =
begin
write_line('</body></html>');
end vypis_konec;
end c_stranka;
end modulek;
Metoda vypis_dynamicky_obsah
zkontroluje, jestli byla odeslßna data z webovΘho formulß°e. Pokud ano, zavolß metodu dej_dynamicky_obsah
a jejφ v²sledek zobrazφ, v opaΦnΘm p°φpad∞ vypφÜe v²zvu pro u₧ivatele. Metoda vypis_konec
za komentß° opravdu nestojφ.
Dojmy a shrnutφ
ModFlex je docela sympatick² projekt. Flex je opravdu zajφmav² jazyk, modern∞ navr₧en², ale postaven² na osv∞dΦen²ch zßkladech. Skripty psanΘ ve Flexu by opravdu mohly b²t spolehliv∞jÜφ ne₧ v PHP. Otßzkou je, zda o to v²vojß°i stojφ - v∞tÜina nadÜenc∙, kte°φ si cht∞jφ co nejrychleji zprovoznit jednoduch² skript asi v²hody tohoto jazyka neocenφ.
Samoz°ejm∞ vÜechno mß svΘ nev²hody, tou nejv∞tÜφ vÜak je pravd∞podobn∞ novost Flexu. P°ekladaΦ jeÜt∞ nenφ ·pln∞ hotov², tak₧e pokud budete chtφt pou₧φt n∞jakΘ exotiΦt∞jÜφ konstrukce, m∙₧e se vßm stßt, ₧e narazφte na hlßÜku typu "feature not implemented". To samΘ platφ o standardnφch knihovnßch, kterΘ jsou zatφm relativn∞ chudΘ (co₧ by ale vadit nemuselo, proto₧e m∙₧ete pou₧φvat knihovny z PHP). Na druhou stranu, samotn² p°ekladaΦ Flexu i modFlex jsou napsßny p°φmo ve Flexu. A takov² p°ekladaΦ, to jsou desetitisφce °ßdek slo₧itΘho k≤du, tak₧e n∞jakΘ nespolehlivosti se bßt nemusφte.