pronto.ee

Tomorrow will be cancelled due to lack of interest

Mäng: “Return to Monkey Island”

“The Secret of Monkey Island” (1990) ja selle jätk “Monkey Island 2: LeChuck’s Revenge” (1991) olid mängud mis silmapilk kolm meest kelleks olid Ron Gilbert, Dave Grossman ja Tim Schafer mängumaailma tippude hulka lennutasid. Nende peategelaseks on asjaarmastajast piraat nimega Guybrush Threepwood, kes üritab muude mereröövlite hulgas endale nime teha ja samal aja Ahvisaare saladuse jälile saada. Loomulikult on tema tee sinna okkaline ning sillutatud vähemal või suuremal määral koomiliste vahejuhtumitega. Erinevalt muudest analoogsetest mängudest kumasid lõbusa pealispinna alt välja mitmed tunduvalt tõsisemad teemad ning sestap lõppeski teine mäng sellise nukravõitu alatooniga.

Nüüd kus peaaegu kolmandik sajandist on selja taha jäänud ning kuhu mahub lisaks neli teiste tegijate poolt valmis sepistatud osa ja paar uusversiooni, otsustasid kaks algset autorit, Ron Gilbert ja Dave Grossman, et aeg on Guybrush tolmust puhtaks kloppida ja vanale ametipostile tagasi kutsuda. Sest vaatamata peategelaste pungutusele pole endiselt selge mis lugu selle Ahvisaare saladusega täpselt on. Nii ilmuski selle aasta 19. septembril sarja seitsmes osa mis kannab nime “Return to Monkey Island”.

Aga. Selgub, et tegemist on siiski kolmanda osaga — mängumeistrid otsustasid vahepeal ilmunud jägesi lihtsalt ignoreerida ja nõnda võib julgelt öelda, et tegelikult on tegemist siiski sarja kolmanda osaga. Seda ühest küljest selle tõttu, et see hakkab pihta täpselt sealt kust teine mäng pooleli jäi ja teisest küljest selle tõttu, et see on esimene mäng pärast teist osa mis kannab endas edasi algsete osade vaimu.

Mängu läbivaks teemaks on lugu mida juba halliseguste juustega Guybrush oma pojale (kelle nimi on — tegelikult ka — Boybrush) jutustab ja räägib kuidas ta lõpuks siiski Ahvisaare saladuse jälile sai. Loomulikult ei puudu selle juurest ka LeChuck, kellele on sama kinnisidee mis peategelasel, Elaine, Voodoodaam ja paljud teised varasematest osadest tuttavad asjapulgad. Kohe alguses selgub, et aeg on edasi läinud ja vanade piraadipealikute asemel laiutavad Scumm baaris noored idupiraatidest (ehk võib neid nii nimetada) tõusikud, kes vana kooli Guybrushile juba sissejuhatavalt viltu vaatavad.

Uue mängu jaoks on Ron Gilbert kirjutanud valmis uue mootori mis kannab nime Dinky. Osaliselt tänu sellele on mängu visuaal mõnevõrra teistsugune kui varasematel osadel, kuid arvestadaes sellega, et tehnilised võimalused on arenenud on see pigem hea. Siinkohas oleks paslik märkida ka seda, et helipildi eest hoolitseb algsete osade muusika autor Michael Land ning tema loodud viisid on lihtsalt maagilised.

Lisaks tehnilistele lahendustele on mängus hulk väikeseid kuid olulisi detaile. Näiteks ei ole ükski mõistatus selline kus tuleb lihtsalt huupi asju kokku panna ja näha mis juhtub. Kõik asjad mängus on loogilised ning täpselt nõnda keerulised, et hallid ajurakud täies mahus koormatud saaks. Kelle jaoks seiklusmängudes nuputamine pole mokkamööda, see võib valida omale lihtsama versiooni kus mõistatusi on vähem ja allesjäänud mõistatused on kergemini hoomatavad. Mängu on sisse ehitatud ka vihjesüsteem ning kui tundub, et enda mõistus enam peale ei hakka võib sealt abi küsida. Esimesed vastused on väga ebamäärased ning kui hammas ikka peale ei hakka, siis järjest konkreetsemad ning selgemad.

Ühe meeldivad detailina pakub Guybrush mängu laadimise ajal, et ta jutustab paari sõnaga lahti mis salvestamise eel toimunud on. See on tegelikult üsna teretulnud siis kui salvestatud mänge on hulgim või kui mängukordade vahele on tekkinud pikem paus ning ei pruugi enam täpselt meeles olla mis teoksil.

Ehk siis kokkuvõtvalt: kui esimesed kaks osa meeldisid, meeldib ka see mäng. Kuigi tehnilised on mäng suhteliselt minimalistlik immitseb sisu ja atmosfääriga seotud kvaliteeti igast mängitud sekundist, mistap ma ei saa muud teha kui seda kindlasti soovitada.

Ning lisaks räägivad kurjad keeled, et see lugu ei jää viimaseks ning autoritel on juba uus mäng tulel.

PHP 8.1: Readonly

PHP

Seekordseks teemaks on PHP 8.1-s sisse toodud uus piirang mille aluseks on readonly muutujad (propertyd).

Kes ei tea, siis readonly muutujat ei saa pärast initsialiseerimist enam muuta, funktsionaalsus mida üsna sageli läheb vaja siis kui andmeid komponentide vahel vahetatakse. Kuni viimase ajani saavutati see funktsionaalsuse getterite ja setteritega. Ma toon ühe näite readonlyst:

<?php

class Test
{
    public readonly string $test;

    public function update(string $test): void
    {
        $this->test = $test;
    }
}

$test = new Test();
$test->update('test');
echo "Initalize";
$test->update('test');
echo "Overwrite";

Kui järgnev kood lasta läbi PHP 8.1-e (varasemate versioonidega ei tööta see üldse), on tulemuseks:

Initalize
Fatal error: Uncaught Error: Cannot modify readonly property Test::$test in /data01/virt58215/domeenid/www.discordia.ee/dev/test.php:9
Stack trace:
#0 /data01/virt58215/domeenid/www.discordia.ee/dev/test.php(16): Test->update('test')
#1 {main}
  thrown in /data01/virt58215/domeenid/www.discordia.ee/dev/test.php on line 9

Nagu näha funktsiooni mis readonly muutujat modifitseerib teistkordne väljakutsumine viskab oodatult exceptioni.

Aga.

Sellel on ka üsna tülikas kõrvalnäht; nimelt on readonly nüüd reserveeritud sõna, mis praktikas tähendab seda, et kui kui teha selline klass:

<?php

class ReadOnly
{
}

… annab interpreteerimisel tulemuse:

Parse error: syntax error, unexpected token "readonly", expecting identifier in /data01/virt58215/domeenid/www.discordia.ee/dev/readonly.php on line 3

Miks see oluline on?

Oluline on see sellepärast, et päris suur hulk erinevaid rakendusi kasutavad ReadOnly klassi kasutajaliideses vaid lugemiseks mõeldud vormielemendi deklareerimiseks. Siinkohas oleks paslik märkida, et see võtmesõna on tõstutundetu, ehk siis sama viga tuleb ka READONLY, readonly, READonly, jne. puhul. Ning siis kui me tahame luua sellenimelisi traite, interfacesi, jne.

Seal on ka üks kentsakas erand: PHP 8.1 lubab deklareerida readonly() funktsioone. Põhjuseks see, et maailma kõige populaarsem sisuhaldusplatvorm WordPress kasutab seda nõnda laialdaselt, et PHP arendajatel ei olnud muud valikut kui seda eraldi lubada.

Jõulud Ukrainas

Kui vahetult enne venelaste sissemarssi Ukrainasse hakkasid levima kõlakad peatsest rünnakust, siis ma ausalt öeldes ei uskunud neid: ukrainlased on sõjakas rahvas kes selleks ajaks oli juba 8 aastat Donbassi piirkonas oma vimma idanaabrite suhtes kogunud. Pealegi on Ukraina ainult kolm korda väiksem kui Venemaa ning valmis kõik oma ressursid sõltumatuse nimel mängu panema. Kui panna siia juurde liitlassuhted ning kultuurilised erinevused siis võib öelda, et Venemaa tungis kallale endaga võrdsele. Strateegiliselt väga mõttetu liigutus ja seega ebaloogiline.

Ometigi vurasid tankid 24. veebruaril üle Ukraina-Vene piiri.

Tagantjärele tarkusena võib öelda, et mu eeldused olid siiski õiged. Selleks hetkeks kui esmane hoog rauges sai selgeks, et praktiliselt kõik Moskva eeldused osutusid valedeks: et iseseisvus pole mitte rahva vaid valitseva kliki tahe, et ukrainlastel pole tahtmist ega vahendeid võidelda, et liitlased vangutavad lihtsalt pead ja teatavad, et nad on äärmiselt mures. Ja loomulikult seda, et Venemaal ei voha korruptsioon ja alkoholism. Oma osa oli siin täita ka Eestil kes esimesena teatas, et Ukrainat tuleb aidata ning isikliku eeskujuna andsime neile OMA kaitseks mõeldud relvi ja laskemoona.

Pool aastat hiljem augustis pärast Põhja-Ukraina täieliku vabastamist sai üldsusele selgeks, et sõda kui selline on tegelikult läbi ning venelased on selle kaotanud. Sellest sai aru üldsus, sellest sai aru Ukraina ja tegelikult sai sellest ka aru Venemaa sõjavägi. Oli saabunud paras aeg leida kompromiss, ohverdada paar ettutit ja taanduda minimaalsete kaotuste hinnaga. Aga nagu selles sõjas juba kombeks oli saanud valiti risti vastupidine suund: kuulutati välja “osaline” mobilisatsioon, vahetati välja sõjaväe juhtkond, ähvardati tuumarelvaga ning keerati kinni gaasikraanid.

Ning visati minema võimalus leida mõlemat osapoolt mingilgi tasemel rahuldav kompromiss.

Selle mõtlematu teo tagajärjed ei andnud kaua oodata: rindel hukkunute arv kahe või isegi kolmekordistus peaaegu üleöö ning äkitselt jõudis sõda Venemaal igaüheni. See ei olnud enam telerist nähtav propaganda, see oli muutunud igapäevareaalsuseks koos kõigi oma koledustega. Sama loomulikult kehtis ka ukrainlaste kohta, aga neil polnud kogu ettevõtmisest mingeid illusioone, nende jaoks oli algusest peale tegemist inimsusevastase kuriteoga. Sajad ja tuhanded inimesed hukkusid iga päev sõjas mille võitja ja kaotaja olid selleks hetkeks juba selged.

Aga mitte sellest ei tahtnud ma rääkida. Seega kerime edasi tänasesse päeva ning arutame mõningasi praeguseid teemasi.

Herson

Hersoni oblast oli üks neljast Venemaa poolt annekteeritud territooriumist vaatamata sellele, et see polnud tervikuna okupantide kätte langenud. Hersoni linn oli ainuke oblastikeskus mis kogu operatsiooni käigus anastajale loovitati. Selle kaotamine oleks venelaste jaoks märgilise tähendusega.

Herson asub Dnepri jõe parem- ehk läänekaldal ja tegemist on umbes Tallinna suuruse linnaga. Sealkandis kasvatatakse suur osa arbuuse mis seletab miks need sel aastal meie poelettidelt puudusid. Venelaste jaoks oli Hersoni linn vaheetapp hõivamaks Odessa ning sõjategevuse peatumine vaid sajakonna kilomeetri kaugusel Dnepri jõest seadis venelased seal äärmiselt ebameeldivasse olukorda.

Mõistmaks mida kujutab endast Dnepr piisab pilgu viskamisest kaardil. Suur osa sellest jõest on umbes poole kilomeetri laiune mis teeb selle laiemaks enamustest Eesti järvedest. Tegemist on loodusliku tõkkega mis on ideaalne siis kui vaenlane on selle taga ja äärgmiselt ebameeldiv kui see ise asub selja taga. Kuna tegemist on nõnda laia jõega, siis viib sellest üle vaid käputäis sildasi millest enamus on konflikti käigus puruks pommitatud. Ainukesena on praeguseks säilinud Kahhovka tamm mille taga asub Kahhovka veehoidla. Venelased on Dnepri läänekalda kaitsmiseks vedanud sinna ohtralt vägesi ja tehnikad mida ei suudeta enam ka parima tahtmise juures varustada.

Mis omakorda on viinud selleni kus okupantidel on tekkinud dilemma: kas kaotada tapetute ning vangistatuna mitukümmend tuhat meest ja kaotada Herson või taanduda ja kaotada Herson. Paarikümne tuhande mehe kaotamine loetud päevade jooksul oleks Venemaa jaoks täielik krahh ning sisepoliitiliselt kui strateegiliselt. Odessa vallutamisest ei ole antud hetkel mõtet enam isegi unistada.

Aga see ei ole ainuke probleem mis neil on. Teine asi on Kahhovka veehoidla. Lisaks hüdroelektrijaamale toimib hiiglaslik veehoidla ka inimtekkelise barjäärina kaitstes Musta mere kaldal asuvaid Moskva vägesi ukrainlaste pealetungi eest. Lisaks väljub sellest kanal mis varustab Krimmi veega ning kuna vask- ehk idakallas on madalamal kui Herson, siis tammi avamisega oleks võimalik vesi peale lasta suurele osale okupantide poolt hõivatud territooriumile. Sestap võib öelda, et venelaste plaan loobuda paremkaldast oli plaan nutuga kurgus.

Ning me ei hakka rääkima siin isegi sellest, et Hersonist on jämedamate torudega võimalik avaldada oma arvamust kõige kohta mis liigub Krimmist mandrile ja vastupidi.

Lühidalt: kas venelased annavad Hersoni ära? Kui see neist kuidagi sõltuks siis ei. Ukrainlased on seal alustanud järjekordset pealetungi ja Moskva teab, et nad ei suuda seda linna ka parima tahtmise juures hoida. Sestap tehakse seal hetkel nägu, et see kõik on plaanikohane paanikavaba manööver.

Valgevene

Hiljuti jooksis meediast läbi jutt kuidas venelased viisid Valgevenesse juurde oma vägesi ning spekuleeriti võimalusega, et Valgevene liitub konfliktiga. Ma pean tunnistama, et Valgevene võimuladvik sai juba algusest peale aimu kust tuul puhub ja sestap nad on väga ettevaatlikult hoidnud oma käsi otseselt veriseks tegemast. Tõsi, nende territooriumi on kasutatud Ukraina ründamiseks kuid ise pole nad mitte ühtegi pauku teinud.

Nüüd kus Venemaa kaotus on ainult vormistamise küsimus on õhku tekkinud küsimus mis saab Valgevenest. Lukašenka on vana rebane ja päris kindlasti ei liitu ta viimasel hetkel kaotajatega. Kuna kompromissikaart on tema jaoks endiselt laual, siis suure tõenäosusega võib juhtuda, et Valgevene tahab ennast Venemaast distantseerida. Moskva jaoks oleks see võrdlemisi valus hoop ning arvatavasti selle vältimiseks sinna hetkel vägesi sisse viiaksegi. Isegi praegu saab Valgevene väita, et kõik tema sõnad ja teod tehti relva ähvardusel ning suures plaanis on nad teinud Ukrainale teene sidudes endaga hulgaliselt väeosi, mis muidu oleks saadetud Ukrainasse.

Talvesõda

Kuigi Ukraina asub Musta mere ääres on talvekülmad seal tihti sama krõbedad kui meil siin. Sel ajal kui Moskva pajatas lühiajalisest sõjalisest operatsioonist varus Kiiev ja liitlased talvevarustust. Tallinnas on hetkel 11 kraadi sooja, Hersonis 10.

Teine teema on sügis, mis sealsed maad mülkaks muudab. See ei ole probleem raudtee ja kergemate sõidutkite jaoks kuid raskemate tankide ning kütuseveokite jaoks see on kriis. Mis tähendab seda, mõnda aega rasketehnika millale venelased on oma panused teinud seal ei liigu. Muide kas te teate kui palju üks tank vajab kütust 100 kilomeetri läbimiseks? Sõltuvalt tankist 300-600 liitrit. Ehk siis senikaua kuniks maa külmab ja transpordiliinid taastuvad hõivavad külamehed taaskord taandumisel hüljatud inventari.

Donetsk

Kas te teate, et Donetski oblasti pealinn Donetsk asub vaid kiviviske kaugusel rindejoonest ning piisab vaid ühest õnnestunud läbimurdest, et see taaskord ukrainlaste kätte langeks. Tegemist oleks taaskord märgilise tähendusega sündmusega, sest Donetsk oli okupantide valduses juba enne praeguse konflikti algust ning oleks omamoodi aknaks Mariupoli. Selle hõivamine tekitaks siseriiklikult hulgalisi küsimus: miks seda konflikti ikkagi alustati? Sestap üritavad Wagner mis on arvatavasti paremini varustatud kui regulaarväeosad sealset rinnet hambad tangis edasi lükata.

Sedavõrd kuidas saabub talv ja kasvab ukrainlaste enesekindlus on tõenäoline, et just siin üritatakse järgmist suuremat läbimurret teha ning on täiesti võimalik, et osaliselt just selle liini tugevdamiseks taanduvad venelased Hersonist.

Transnistria

Transnistria on omamoodi fenomen. See kuulub ametlikult Moldovale, aga Vene separatistid on seal loonud oma järjekordse sõltumatu vabariigi. Selle käigus kerkis ülesse relvastatud konflikt mis päädis Vene baaside sinna viimisega. Seega on oma olemuselt tegemist okupeeritud territooriumiga.

Samas on aeg edasi läinud, noored on äärmiselt vaesest Transnistriast juba ammu jalga lasknud ja ainsad elanikud kes sinna on jäänud, on pensionärid. Nüüd tuleb mängu huvitav osa — Transnistria asub täpselt Moldova ja Ukraina vahel ning Ukraina võib ja ilmselt otsustabki ühel hetkel, et see järjekordne isehakanud riik koos sealsete baasidega on ohuks nende julgeolekule. Sealne Vene kontingent oleks Ukraina vastu suhteliselt abitu; seda enam, et Moskval pole ukrainlasi mitte millegagi enam ähvardada. Ning kui Moldova ametlikult kätt ette ei pane — milleks tal pole põhjust — lakkab enklaav aasta jooksul eksisteerimast.

Venemaa

Hiljuti viidi Moskvas läbi tänavaküsitlus, et mis saab siin kui Venemaa kaotab sõja Ukrainaga. Isegi kõige tulisemad sõjavastased ei saanud sellest küsimusest aru — see oli nende jaoks võimalis mis oli nende jaoks juba eos välistatud. Ma arvan, et senikaua kuniks selline seisukoht on valdav ei ole mõtet lahendust otsida. Kõigepealt peab rahvale kohale jõudma, et kaotus on täiesti arvestatav võimalus. Hinnanguliselt peab sõda selleks ajaks jõudma peaaegu igasse peressem iga inimeseni mis tähendab praktikas kusagil 200000-3000000 hukkunud ning sellega vastavas suhtarvus haavatuid, vaimselt/füüsiliselt sandistunuid, vangi langenuid, ülejooksnuid, deserteerunuid.

Praeguse tempo juures jõuab see kohale jõuludeks-aastavahetuseks. Senikaua võtab vikatimees seal paraku lõivu.

PHP8: tüübimaagia

PHP

PHP8 tõi sisse hulgaliselt täiendusi tüüpidega majandamisesse ning PHP8.1 lisas sinna omakorda peale täiendava kihi. Selles postituses keskendume me siiski vaid PHP8 muudatustel.

PHP on n.ö. nõrkade tüüpidega (weak typing) keel, mis praktikast tähendab seda, et erinevaid tüüpe on võimalik võrrelda ja nende väärtuseid teineteisele omistada; selleks vajalik tüüpide kantimine (type coercion) toimub automaatselt. Teinekord paraku soovimatute kõrvalnähtudega. PHP8 üritab jõudumööda neid soovimatuid kõrvaltoimed kas siis vältida või vähemalt pakub võimaluse neid kontrolli all hoida.

Tüüpide võrdlemine

Klassikaline erinevus PHP7 ja PHP8 vahel ilmneb järgnevas võrdluses:

if ('something' == 0) {
    echo 'true';
} else {
    echo 'false';
}

Nii 'something' kui 0 võivad olla muutujad; PHP7 puhul on vastuseks true, PHP8 puhul false. Asi on selles, et kui võrdluses on int ja string, siis proovitakse stringist teha int. Kuna tegemist on mittenumbrilise tekstiga, siis PHP7 pani selle väärtuseks 0 sellal kui PHP8 jaoks väärtus puudub ja sellest ka erinev tulemus. Samasuguse tulemuse annab näites järgnev lõik:

if ('42something' == 42) {
    echo 'true';
} else {
    echo 'false';
}

Selline tüüpide kantimine on teinekord väga mugav, näiteks XML failide töötlemisel, kuid sisaldab endas riske ja tänu sellele võib juhtuda, et kood mis toimis PHP7-s ei tööta enam PHP8-s. Märkuseks nii paljud, et:

if ('42' == 42) {
    echo 'true';
} else {
    echo 'false;
}

… on true vaatamata PHP versioonile, kuna ’42’ on string mida on võimalik üheselt intiks kantida.

Muudatus tüüpide kantimises torkab silma ka siis kui kasutada < ja > võrdluseid. Kui varem kanditi string intiks ja seejärel võrreldi, siis nüüd kui stringi ei ole võimalik konvertida on number alati väiksem kui string. Need nüansid laienevad muudelegi võrdlustele, näiteks in_array käitub nüüd pisut erinevalt.

Ma siiski tooks enne järgmise näite juurde minekut eraldi välja erisuse kui kasutada switchi.

switch(0) {
    case 'a' : print "case A\n"; break;
    case 0   : print "case 0\n"; break;
}
 
switch('a') {
    case 'a' : print "case A\n"; break;
    case 0   : print "case 0\n"; break;
}
 
switch(0) {
    case 0   : print "case 0\n"; break;
    case 'a' : print "case A\n"; break;
}
 
switch('a') {
    case 0   : print "case 0\n"; break;
    case 'a' : print "case A\n"; break;
}

Annab PHP7 puhul tulemuseks

case A
case A
case 0
case 0

ja PHP 8 puhul

case 0
case A
case 0
case A

Mis on eelnevat arvestades igati loogiline ja enamasti ka soovitud tulemus. Ehk siis nõrkade tüüpidega manipuleerides võib juhtuda, et kood käitub pisut teisi.

Unionid

PHP7 tõi keelde funktsioonide pöördumistüübi ning PHP7.1 nullitavad tüübid (nullable types). Et vältida soovimatut tüüpide kantimist ning aidata IDE-si soovituste andmisel on funktsioonidel võimalik anda tüüp nii sisendi kui väljundi jaoks. Nullitavad tüübid (algavad ? märgiga) näitavad, et tüüp võib (näiteks kui vastus ei leita) olla ka null. Näide:

public function doStuff(int $i): ?string
{
    // stuff
}

Aga mis siis kui sisend (või väljund) võib olla rohkem kui ühte tüüpi? Iseenesest pole midagi valesti selles kui muutujaid kanditakse enne või pärast funktsiooni välja kutsumist kuid see on tülikas, lisab ballasti ja ei aita loetavusele kaasa. Sestap tõi PHP8 sisse unionid. Näide:

public function add(int|float $a, int|float $b): int|float
{
    return $a + $b;
}

Märkuseks niipalju, et null ei tegelikult tüüp, vaid tüübi puudumine ja sestap ei ole string|null endiselt korrektne konstruktsioon ja selle asemel tuleks kasutada ?string tüüpi.

mixed tüüp

Teinekord on vaja lihtsalt konstruktsiooni kus lubatud on kõik tüübid KAASA ARVATUD null. Selleks puhuks tõi PHP8 sisse pseudotüübi nimega mixed. Näiteks:

public function doStuff(mixed $input): bool
{
    // stuff
}

Muutujad mille tüüp pole veel selge tüüp on samuti mixed. Kuna mixed sisaldab kõiki tüüpe ei oma int|mixed ja ?mixed mingit tähendust ning annavad seetõttu vea. Samal põhjusel ei eksisteeri is_mixed funktsiooni ning samuti ei ole võimalik teha $b = (mixed)$a.

Üks asi veel: alatest PHP8-st ei ole enam võimalik deklareerida klassi nimega mixed. Kuni sinnamaani oli see teoreetiliselt võimalik.

PHP8: konstruktori parameetrite eskaleerimine

PHP

Konstruktori parameetrite eskaleerimine (Constructor Property Promotion) on tõenäoliselt kõige praktilisem uuendus mille PHP8 endaga kaasa tõi. Ühes dependency injectionite ja reflectionite järjest laialdasema kasutamisega näeb tavalise konstruktori signatuur koos parameetrite, muutujate ja omistustega välja umbes selline:

protected Database $database;
protected Config $config;
protected Source $source;

public function __construct(Database $database, Config $config, Source $source)
{
    $this->database = $database;
    $this->config = $config;
    $this->source = $source;

ning objekti enda initsialiseerimine selle klassi põhjal selline:

$adapter = new Adapter($database, $config, $source);

Keerukamate rakenduste puhul kasutavad objektid kümneid muid objekte eriti kui mängus on reflectionid mis initsialiseerimise poole suuresti automatiseerivad ja arendajat seoserägastikuga kaasnevast peavalust säästavad. Paraku tingib see samas olukorra kus injectioneid tehakse väga kergekäeliselt ning iga klassi konstruktoris on hulgaliselt parameetreid mis siis ükshaaval klassimuutujate külge kleebitakse. Ning tõsisemates raamistikes / rakendustes on klasse sadu kui mitte tuhandeid.

See on nüri, see võtab aega, see muudab koodi pikaks ja ühes sellega loetamatuks.

PHP8-s näeb analoogne kood välja selline:

public function __construct(protected Database $database, protected Config $config, protected Source $source)
{

Kui erandjuhud näiteks referentside (need & märgiga algavad muutujad) näol kõrvale jätta, on parameetrites deklareeritud muutujate skoop ja ühes sellega nähtavus alati piiratud funktsiooniga. Erandiks on PHP8-s konstruktor kus nähtavuse lisamine ütleb klassile, et nähtavusega muutujad tuleb automaatselt eskaleerida klassiüleseks ning nende nähtavus (private, protected, public) oleks mida iganes nende nähtavuseks määrati. Muutujad millel nähtavust pole jäävad endiselt vaid konstruktorile endale nähtavaks.

Nagu näha on see tükk maad lühem, loetavam ja suures plaanis on seal palju vähem ruumi vigadele. Seal on siiski mõned nüansid millega peab arvestama:

  1. Eskaleerivaid muutjaid saab deklareerida AINULT konstruktoris
  2. Nõnda deklareeritud muutujaid EI SAA uuesti (eraldi) deklareerida
  3. Variadic muutujaid EI SAA eskaleerida
  4. Callable tüüpi muutujaid EI SAA eskaleerida
  5. Abstract konstruktorid EI TOETA eskaleerimist.

Enamus neist ülaltoodud piirangutes on tegelikult äärmiselt loogilised ning kui nende üle mõelda aitavad mõista eskaleerimise olemust. Seega eskaleerigem mõnuga!

PHP8: nullikindel operaator

PHP

Vajadus nullikindla operaatori (null-safe operator) järele eksisteerib PHP-s juba mõnda aega. Põhimõtteliselt võimaldab see nüüd kasutada pöördumisväärtuste ahelat ilma täiendavate kontrollideta ka siis kui seda kasutatakse koos väärtustamata tüüpidega (nullable types).

Et sellest paremini aru saada tuleb vaadata mõlemat asja eraldi. Väärtustamata tüübid lisati PHP-sse hulk aastaid tagasi versioonis 7.1. Klassikaline väärtustamata tüübiga meetodi signatuur näeb välja selline:

public function getSession(): ?Session
{
    // Code
}

Praktikas tähendab see seda, et kirjeldatud funktsioonil võib olla kahte tüüpi pöördumisväärtus: Session või null. Null on spetsiifiline tüüp mida kasutatakse sellistel puhkudel kui väärtust ei leita: näiteks antud juhul oleks täiesti legitiimne viis tagastada null kui sessioon on initsialiseerimata. Siinkohas on oluline mõista, et see on legitiimne viis ainult siis kui tõepoolest selline olukord on loomulik voo osa, näiteks sellisel puhul kui kasutaja pole sisse loginud. Kui sessiooni ei ole ühel või teisel (tehnilisel) põhjusel võimalik pärida, siis on korrektseks lahenduseks Exceptioni viskamine. See võimaldab vahet teha vastuse puudumisel ja veal.

Tähelepanuks niipalju, et väärtustamata tüüpe võib kasutada ka sisendaväärtustena. Näiteks:

$user->setAddress(?Address $address);

Tüüpide kasutamine pole tänapäeva PHP-s küll otseselt kohustuslik kuid sellele vaatamata rangelt soovituslik; see võimaldab IDE-del automaatselt tuvastada koodis vigu ning vältida olukorda kus funktsioonile antakse ette vale parameeter mille PHP automaatselt ootamatute tagajärgedega enda jaoks sobivaks konverteerib.

Pöördumisväärtuste ahel on PHP veelgi kauem eksisteerinud. Klassikaline ahel näeb välja selline:

$country = $app->getSession()->getUser()->getAddress()->getCountry();

See võimaldab juhul kui pöördumisväärtuseks on objekt selle meetodeid koheselt kasutada. Probleem tekib siis kui mõne meetodi pöördumisväärtuseks on null. Sellistel puhkudel on tulemuseks: Fatal error: Uncaught Error: Call to a member function getSession() on null in .... Kuna eelnevalt sai toonitatud, et null võib olla meetodil täiesti legitiimne pöördumisväärtus sunnib see arendajat iga pöördumisväärtust eraldi kontrollima mis oma olemusel muudaks kogu kontseptsiooni kasutuks.

PHP8 tõi sellele probleemile lahenduse nullikindlate operaatorite (null-safe operators) näol. Praktikas näeb see välja selline:

$country = $app->getSession()?->getUser()?->getAddress()?->getCountry();

Sellisel puhul kui ükskõik milline ülaltoodud meetod annab tagasi null väärtuse, lõpetatakse ilma veata ahela edasine täitmine ning muutuja $country saab väärtuseks null. Selline lähenemine muudab koodi oluliselt lühemaks ja loetavamaks.

Oluline on siiski pidada silmas paari nüansse:

  1. ?-> tuleks kasutada ainult siis kui pöördumisväärtus võib reaalselt null olla. Vastasel korral on see probleemi vaiba serva alla lükkamine ehk siis reaalne viga võib arenduse käigus märkamata jääda.
  2. Seda saab kasuatada ainult lugemiseks. Muutujaid selle kaudu omistada ei saa. Näiteks $country()?->countryCode = 'EE'; annab tulemuseks Fatal error: Can't use nullsafe operator in write context in …
  3. See operaator annab varasemata PHP versioonidega vea: Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR) in …
  4. Seda meetodit ei ole võimalike kasutada läbi viidete (references): &$country->getCode(); annab tulemuseks: Fatal error: Cannot take reference of a nullsafe chain in …

PHP8: match avaldis

PHP

Ma olen viimastel aastatel päris palju pidanud algajate arendajate koodi hindama ja üks asi mis mulle silma torkab on see kui harva kasutatakse switch-i tingimuste lahendamiseks. Selle asemel leiab koodist erineval kujul terve leegioni if, else ja elseif lauseid. Ma ei hakka sellest hetkel pikemalt pajatama; jätke lihtsalt meelde, et switch on teie sõber. Kui seda õigesti kasutada siis muudab see koodi loetavamaks ja lühemaks.

PHP8 tõi sisse uue viisi tingimustega tegelemiseks mis on segu switch-ist ja kolmekordsetest (ternary) operaatoritest. Kui ei tule kohe meelde mida kolmekordne operaator endast kujutab, siis tüüpiliselt näeb see välja selline:

$i = $condition ? 'true' : 'false';

Uue viisi nimi on match ja kui tingimused klapivad, siis muudab see koodi veelgi lühemaks ja veelgi loetavamaks. Pidage meeles, et iga rida koodi on midagi mida tuleb jooksvalt hooldada ja vajaduse korral uuendada. Kui loetavus sellest ei kannata, siis mida vähem koodi seda parem. Toon siinkohas ühe näite kasutades eelmises postituses mainitud anonüümseid funktsioone:

$animal = 'dog';

$voice = match($animal) {
    'dog' => function() {return 'woof';},
    'cat' => function() {return 'meow';},
    'poro' => function() {return 'perkele!';},
    default => function() {return 'huh?';}
};

echo $voice();

Siinkohas oleks paslik ära märkida paar nüanssi. Esiteks match eeldab, et muutuja $animal on deklareeritud. Kuigi ta selle peale tööd ei katkesta ning väärtustab tulemi default-iga, kuvab ta vaikimisi hoiatuse: Warning: Undefined variable $animal

Teiseks on oluline, et match-i parameeter ja väärtus millega võrreldakse ('dog', 'cat', jne.) oleks sama tüüpi. Näiteks kui võrrelda väärtuseid 1 ja '1', siis on tulemuseks default. See on sarnane PHP === võrdlusega, kus erinevaid tüüpe ei ühtlustata nagu tehakse == võrdluse puhul.

Kolmandaks PEAB valik sisaldama tõest väärtust (kasvõi default-i näol). Kui lahendit ei leita on tulemuseks: Fatal error: Uncaught UnhandledMatchError: Unhandled match value of type string in ...

Teinekord kasutavad arendajad analoogse tulemuse jaoks nimelisi massiive:

$animal = 'dog';
$voices = [
    'dog' => function() {return 'woof';},
    'cat' => function() {return 'meow';},
    'poro' => function() {return 'perkele!';}
];

echo $voices[$animal]();

Sellel on kaks eelist: esiteks nagu näha on see ilma kontrollideta veelgi lühem ja teiseks töötab see varajasemate PHP versioonidega. Samas ei toeta see default-i mis praktikas tähendab seda, et tuleb kontrollida kas sellise nimega element eksisteerib, funktsioonid deklareeritakse isegi siis kui neid ei kasutata (see ei ole probleem kui väärtuseks on skalaarmuutujad nagu int, float, string jne.) ja tüüpi ei kontrollita. Sellise lahenduse kasutamine on iseenesest samuti ok ehk siis valik tuleb teha lähtuvalt ülaltoodud piirangutest.

PHP8: create_function() eemaldati

PHP

Ma olen viimased kuu aega PHP8 sees ringi mütanud eesmärgiga aru saada mis sealt uut leiab ja kuidas sellest võimalikult palju kasu lõigata ning olen sealt leidnud päris mitu tähelepanu väärivad asjad. Püüan osadest neist paari sõnaga kirjutada.

Selle konkreetse postituse teemaks on create_function() nimeline funktsioon, õigemini selle puudumine PHP8-s. Algselt lisati see PHP4-le ning selle mõte oli tuua PHP-sse anonüümsed funktsioonid. PHP5-e viimastes versioonides muudeti see kõik juba keele osaks, kuid mingil seletamatul põhjusel jätkas suur hulk arendajaid selle funktsiooni kasutamist vaatamata sellele, et funktsiooni MITTE kasutamiseks oli päris mitu head põhjust; näiteks kasutab nõnda loodud funktsioon globaalset mälu ning seda ei ole võimalik vabastada. Kuna tegemist on jõhkra häkiga kuulutati see PHP 7.2-s eemaldamisele minevaks ning alates PHP8-st kustutati see üldse maha.

Mis omakorda tähendas seda, et kui PHP-s kirjutatud tarkvara kasutas seda funktsiooni tervitab selle kasutajat pärast uuendamist järgmine veateade: Uncaught Error: Call to undefined function create_function() in <fail>. Kuna pahatihti kasutasid seda WordPressi kujunduste ja moodulite kirjutajad tähendas see seda, et pärast PHP versiooni vahetamist loobus nii mõnigi veebisait koostööst. Eriti siis kui tegemist oli pikemat aega toiminud leheküljega ja vaatamata sellele, et platvorm ise oli viimase versiooni peal.

Õnneks on seda probleemi suhteliselt hõlbus parandada. Panen siia ülesse ühe näite. Kõigepeal näide mis PHP8-s EI tööta:

$function = create_function('$a,$b','return $a . \' \' . $b;');
echo $function('Hello', 'World!');

Ja nüüd näide mis töötab:

$function = function($a, $b) {return $a . ' ' . $b;};
echo $function('Hello', 'World!');

Nagu näha on teine näide loetavam, elegantsem ja võtab vähem ressursse. Ning selle juurutamine ei ole üldse keeruline.

Ehk on abiks.

Sõjaprintsess

Pereäri on juba mõnda aega peaminister Kaja Kallase kallal tänitanud ning teda irooniliselt sõjaprintsessiks nimetanud. Täna proovis sama meedia veergudel teha Keskerakonna juhatuse ning Riigikogu liige Jaanus Karilaid. Paar tundi hiljem olid ta kuraasikad sõnad juba sootuks nutusemad, sest Kaja Kallas saatis praeguse valitse laiali ning tegi uue valitsuse moodustamise ettepaneku sotsidele ja Isamaale.

Antud juhul ma ei tahaks Karilaiul sõnavõttudel rohkem peatuda või kui siis ehk niipalju, et minu arvates on pärast paari nädala pikkust valitsuse töö saboteerimist ja hoogsat selga pussitamist kohatu süüdistada peaministrit reetmises.

Enne potentsiaalsete kombinatsiooonide kallale minemist tahaks kombata korraks hetkeolukorda, eelkõige seda milline on Reformi positsioon.

Reformierakonna olukorda pole ammu olnud nõnda hea kui praegu, seda suuresti praeguseks juba eelmise valitsuse tegutsemisele Vene-Ukraina sõja puhkedes. Eesti oli üks esimesi, kes andis kriitilistel hetkedel Ukrainale abi nii relvade kui eeskujuga. Sel ajal kui suurem osa Euroopast oli ähmi täis saatis Eesti Ukrainale Javeline ja muud moona, veenis oma partnereid kiiresti tegutsema ning oli venevastaste sanktsioonide ning Ukraina igakülgses abistamises eeskujuks ning jalgade lohistajate tagantutsitajaks. Rahvas mõistis vajadust selle järele ning see kajastus üheselt ka Kaja Kallase toetuses.

Kuid mitte ainult. Keskerakond kelle sidemed Vene praeguse võimuladvikuga pole tegelikult kunagi saladus olnud on jätkuvalt kaotanud oma toetust olles praeguseks langenud endiselt kindlalt esimeselt kohalt kolmandale (olles lühikest aega isegi neljandal Eesti 200 kannul). Nende jaoks on praegune peaminister olnud sõja algusest saati olnud äärmiselt mõru pill. Sama kehtib ka EKRE kohta — selle erakona sõnad ja teod on harva ühtinud ning kuidas nende toimetamisi ka tõlgendada proovida, nende teod kipuvad olema pigem praeguse idanaabri režiimi toetavad. Mõlema positsioonid on pärast konflikti algust olnud selges langustrendis ja kogu sellest tingitud nagistamine on viinud praeguse olukorrani.

Reformil on tegelikult laual viis võimaliku stsenaariumit.

Üks on see, et Isamaa võtab kutse vastu. Sellele räägivad vastu Isamaa ninameeste häälekad sõnavõtud mida on nüüd juba hilja tagasi võtta. Ma arvan, et Reform tegi selle pakkumise viisakusest, eesmärgiga Isamaad halba valgusesse mängida. Ütleme nii, et Isamaa ise on ennast ise lollilt nurka värvinud ja rumal oleks seda olukorda mitte ära kasutada.

Teine variant on see, et Reform läheb koos SDE-ga (kes on praeguseks oma põhimõtteliselt nõusoleku juba andnud) vähemusvalitsuse teed. Asi on selles, et Keskerakonna ning kohati ka Isamaa liikmed ei ole sugugi nõnda üheselt praeguste juhtkondade selja taga. Eriti Keskerakonna puhul on lähitulevikus oodata suuremat sorti aadrilaskmist ja seda just ladvikust. Vabalt võib juhtuda, et Reform leiab Keskerakonna ja Isamaa liikmete poolt piisavalt toetajaid, et järgmiste valimisteni vastu pidada.

Mis omakorda viib kolmanda, kõige tõenäolisema, stsenaariumini — Reform soovib välja kutsuda erakorralised valimised. Selleks on vaja põhimõtteliselt 51 Riigikogu liikme toetust; seda on küll pisut raske läbi viia kuid antud hetkel on asi ilmselgelt küünaid väärt. Põhimõtteliselt on see sarnane eelmise stsenaariumiga ning kui Isamaale jõuab kohale kogu probleemi ulatus võib juhtuda, et nad on kõigeks valmis, peaasi, et seda ei juhtuks. Sest eksisteerib reaalne oht, et Isamaa ei ületa erakorraliste valimiste puhul künnist.

Neljas variant on loomulikult see, et Reform läheb opositsiooni. See on Reformi jaoks tõenäoliselt kõige lihtsam ja üldsegi mitte halb variant: sügisel on uuesti päevakavas energiakriis, mis tänu sanktsioonidele on tõenäoliselt suurusjärk hullem. Lisaks loomulikult COVID-i uus laine ning hea oleks näha kust see lastetoetuse raha lõpuks siis välja võetakse. Nii või teisiti poleks oma väikeste käpakeste kogu jamast puhtaks pesemine oravate jaoks täiesti vastuvõetav väljavaade. Seda enam, et tekkiv kolmikliit oleks äärmisel nõrk ning suuresti teovõimetu. Mis omakorda võib lõpuks ikkagi viia kolmanda variandini.

Eksisteerib ka viies variant, mis on küll arvestades hetkeseisu ja nappi aega ebatõenäoline kuid samas ei saa seda välistada: Keskerakonnas veerevad mõned pead, erakond kas läheb lõhki või toimub paleepööre. Suurele osale KE-st ei ole vastuvõetav uuesti EKRE-ga koostöö alustamine. Põhimõtteliselt oleks sellisel puhul teise variandi derivaadiga.

Ehk siis eks näeme. Sõjaprintsessi gambiidi esimene käik on tehtud.

Film: “Apteeker Melchior”

“Apteeker Melchior” on kahtlemata viimase aja suurim Eesti film ning võimalik, et tegemist on meie kino omamoodi taaskäivitajaga. Eesti filmikunsti läbivaks teemaks on aastakümneid olnud tõekspidamine, et kui publikul kinost väljudes must masendus peal ei ole siis on lavastaja midagi valesti teinud. Seda ootust on süstitud nii lavastajatesse, näitlejatesse, kriitikutesse kui publikusse. See on põhjus miks Eesti film piiri taga läbi lüüa ei suuda. Sest meil ei suudeta mõista mis on kino. Et kino on eelkõige meelelahutus.

Kui ma peaksin kellelegi rääkima miks tuleks “Apteeker Melchiori” vaadata, siis ma ütleks, et kõigepealt oli “Viimane reliikvia”, siis periood mida iseloomustab 50 halli varjundit ja seejärel tuli “Apteeker Melchior”. See film (ja eelkõige just raamatud millel see film baseerub) on omamoodi “Viimse reliikvia” eellugu.

Lisaks ma ütleks, et eelarvet silmas pidades näeb see hea välja, on lustakas ja meelelahutuslik. Eraldi tahaks välja tuua veel Marko Matvere komptuur Spanheimi kehastust – mees on sõjas käinud ja elu näinud, teab palju, aga oskab keelt hammaste taga hoida. Ta on usutavalt autoritaarne ning autoriteetne, ta mehed alluvad talle tingimusteta. Hea töö Matvere poolt.

Kõike eelnevat kokku võttes: Kas film on kinoskäiku väärt? Kindlasti jah.

Aga.

Nagu sellistel puhkudel ikka on medalil teinegi pool. Filmi aluseks peaks vähemalt teoreetiliselt olema Indrek Hargla raamat nimega “Apteeker Melchior ja Oleviste mõistatus”. See räägib Oleviste kiriku ehitamisest ning mõrvamüsteeriumist mille oluliseks tegelaseks on Tallinna linnaapteeker Melchior. Esimese vihje kuivõrd meelevaldselt on tsenaristid ümber käinud algmaterjaliga annab juba algkaadrites olev Tallinna siluett kus valmis Oleviste kirik on kesksel kohal. Peatselt selgub, et sündmused toimuvad Tallinnas vaid nime poolest ning kuigi peategelane peaks justkui olema apteeker on ta pigem üks noorhärra, kes elab pudelikesi täis butiigi tagatoas.

Miks ma ütlen, et koht on Tallinn vaid nime poolest? Hargla on raamatud kirjutades kõva kodutöö teinud: kus vähegi võimalik on on sündmused ning linnaga seotud nüansid ajalooliselt korrektsed ning paiknevad õigetes kohtades. See kõik on filmis allavett lastud ning Tallinnas on saanud ebamäärane keskaja linn mis võib asuda ükskõik kus. Põhimõtteliselt on filmist väja roogitud kõik mis oleks ühte või teistviisi hariv.

Teine asi on muidugi apteeker ise. Melchior on saksamaalt pärit mees, kellel pikk ja sünge minevik mis raamathaaval järjest lahti rullub, perekonna needus ning miks täpselt ta on siia tsivilisatsioonide kokkupuutepunkti tulnud ei ole siiamaani päris selge. Melchior Wakenstede on ise sakslane samas kui tema naine Keterlyn on eestlane (nagu ka näiteks usumees Hinric). Filmis lähevad sellised nüansid täielikul kaotsi ning kuna see muutub raamatust raamatusse minnes üha olulisemaks, muutub pärast planeeritud filmitriloogiat loo kinolinal jätkamine raskeks kui mitte võimatuks. Melchior lihtsalt ei saa olla apteeker.

Kolmas asi on lavastaja, stsenaarium ja näitlejad. Kui Marko Matvere kõrvale jätta, siis paraku kumab teostuses läbi teatrilavastaja taust ning tõik, et näitlejad ei esita mitte rolli, vaid kannavad ette stsenaariumisse kirja pandut. Dialoogid on puised, osatäitmised siin ja seal planeerimatult koomilised ning need kohad mis pidid olema koomilised on lihtsalt piinlikud. Lisaks kui paar verisemat kohta kõrvale jätta, on kogu lugu naiivne ning tegemist on pigem noortele mõeldud linateosega.

Ehk teisisõnu. Võrreldes ülejäänud Eesti filmidega on “Apteeker Melchior” jõudnud punkti, kus puude taga hakkab juba mets paistma. Ehk aitab see Eesti filmitööstusele lõpuks jalad alla saada: palju on tehtud, aga palju on veel minna.

Üks detail veel — kui vähegi võimalik vaadake seda filmi enne raamatu kallale asumist, sest siis ei ole need probleemid nii frustreerivad.

Pages:1234567...145