Hlavní navigace

Squeak: návrat do budoucnosti (7)

23. 3. 2004
Doba čtení: 10 minut

Sdílet

Pro dnešek opustíme výklad jazyka Smalltalk a podíváme se blíže na Squeak. Popíšeme si jeho strukturu, řekneme si něco o zdrojových kódech a přiblížíme si proces vytváření a přenosu vlastních aplikací.

Squeak je jednou z nejmladších implementací Smalltalku. Ovšem vzhledem k tomu, že vychází z původní implementace Smalltalku-80, přímo navazuje na práci vývojářů z PARC a část z nich se na vývoji Squeaku také nemalou měrou podílí. Když spustíte nejranější verze Squeaku (ftp://st.cs.u­iuc.edu/Smalltal­k/Squeak/1.1/), dostanete krom barev a podpory zvuku víceméně původní prostředí Smalltalku tak, jak bylo na trh uvolněno v roce 1983 (screenshot). Velká část virtuálního stroje Squeaku je generována přímo Squekem. To krom toho, že lze zkoumat a měnit střeva VM přímo v příjemném smalltalkovském prostředí, mělo za následek i jeho snadné portování na celou řadu platforem.

Jak jsme si v prvním dílu našeho seriálu řekli, vyžaduje Smalltalk pro svůj běh virtuální stroj a image. U Squeaku je virtuální stroj reprezentován typicky jedním souborem (squeak, Squeak.exe…). Využívá pluginy, které sice většinou bývají sestaveny přímo s VM (např. pluginy pro síťové rozraní, zvuk apod.), ale některé z nich jsou přikládány ve formě dynamických knihoven (typicky třeba FFI umožňující ze Squeaku volat funkce z jiných dynamických knihoven hostitelského operačního systému). Virtuální stroj Squeaku má velikost cca 1 MB.

Image je obrazem objektové paměti Smalltalku. Jedná se o platformně nezávislou část a lze ji tudíž libovolně přenášet. Obsahuje fyzickou reprezentaci všech ve Smalltalku přítomných objektů, které jsou při jeho spuštění nahrány do paměti. Specifická situace je kolem metod. Metody jsou v image uloženy ve zkompilované podobě, tedy ve formě bytekódu. Tuto binární podobu můžete získat pomocí výrazu

MojeTrida methodDictionary at: #selektorZpravy.

Výsledkem je instance třídy CompiledMethod dědící ze třídy ByteArray. Pro zajímavost, počet všech metod ve Squeaku zjistíte např. výrazem CompiledMethod allInstances size. Měl bych zdůraznit, že vždy je kompilována každá metoda zvlášť. V image nejsou ukládány zdrojové kódy. Máme-li například následující text metody

plusDays: anInteger
    "Answer a TimeStamp which is anInteger days after the receiver."

    ^self class date: (self date addDays: anInteger) time: self time 

je přeložen do bytekódu a do image uložen následovně:

21 <70> self
22 <C7> send: class
23 <70> self
24 <D2> send: date
25 <10> pushTemp: 0
26 <E1> send: addDays:
27 <70> self
28 <D3> send: time
29 <F0> send: date:time:
30 <7C> returnTop

Zdrojové kódy metod nejsou pro běh aplikací nutné a zbytečně by zabíraly místo. Proto jsou ukládány mimo image, slouží k tomu dva soubory – sources a changes. K rozdělení zdrojových kódů se přistupuje z ryze praktických důvodů. Pro jejich ukládání se primárně používá soubor sources. Je to obrovský textový soubor obsahující definice tříd, jejich dokumentaci a texty metod. V současné době má cca 14 MB.

Soubor changes se zavádí, aby soubor se zdrojovými texty nemusel být neustále distribuován celý. Obsahuje pouze změněné definice. V okamžiku, kdy Squeak ve svém vývoji dosáhne celočíselné verze (v současnosti 3.x), zavolá se příkaz Smalltalk condenseSources, čímž jsou všechny změny aplikovány na soubor sources a obsah changes je zrušen. Pokud se dále provádí v systému nějaké změny, jsou ukládány pouze do souboru changes. Ten podporuje verzování, díky čemuž můžete procházet historii změn jednotlivých metod, vracet se ke starším verzím, porovnávat je apod.

Všichni uživatelé hostitelského systému mohou sdílet virtuální stroj a soubor sources. Jednotlivým uživatelům pak stačí pouze vlastní verze image a pro ni příslušný soubor changes. Rovněž pokud vyjde nová oficiální verze Squeaku, stačí distribuovat pouze novou image a changes, protože VM a soubor sources zůstávají nedotčeny.

Zajímavá situace nastane v případě, že z nějakého důvodu – např. kvůli šetření místem – soubory changes a sources k dispozici nemáme. Pro běh systému to nevadí, ovšem co se stane, pokud chceme provádět v systému nějaké změny či prohlížet jeho zdrojové texty? Kupodivu příliš omezeni nebudeme. Pokud jste dosud považovali tvrzení, že „pro Squeak není pojem open source záležitostí licence, ale funkčnosti“, za nadnesenou reklamní frázi, je na čase změnit názor. Díky jednoduchosti bytekódu a poměrně triviálnímu překladu umožňuje Squeak velmi věrnou dekompilaci. Například výše uvedená metoda v dekompilovaném stavu bez zdrojových textů vypadá takto:

plusDays: t1
    ^ self class
        date: (self date addDays: t1)
        time: self time

Jak vidíte, přišli jsme o originální formátování, komentáře, původní jména lokálních proměnných a parametrů, ale výsledek je stále dobře čitelný, protože základní struktura a selektory zpráv zůstaly zachovány. Celé vývojové prostředí se přitom chová stejně, jako byste zdrojové texty k dispozici měli. Práce se soubory changes a sources je v režii samotného Squeaku. Díky tomu existují například hacky, které umožňují běžně pracovat se souborem sources, přičemž ten je ale ve skutečnosti uložen ve spakovaném souboru o zhruba třetinové velikosti. Do VM přitom není třeba nijak zasahovat.

Máme virtuální stroj, image a soubory se zdrojovými texty. Jak ale s těmito prostředky vytvořit nějakou aplikaci? Na Smalltalk se lze dívat z mnoha pohledů. Od začátku byl koncipován jako desktopový jednouživatelský operační systém. Má vlastní plánovač procesů, grafické rozhraní, image lze do paměti nahrát z prakticky libovolného zdroje, třeba i nenaformátovaného disku. Tento pohled je nejjednodušší, ale u současných Smalltalků zcestný.

Smalltalk jako samostatný operační systém je velmi lákavá představa. Uniformní struktura, naprostá otevřenost, jednoduchost a flexibilita takového systému by jen stěží nacházely s čímkoliv srovnání. Nicméně v současnosti Smalltalku chybí celá řada vlastností nezbytných pro moderní operační systém. V první řadě se jedná o oddělení jádra systému a bezpečný víceuživatelský režim. Nejedná se sice o nic, s čím by si v principu nedokázal poradit, nicméně implementace by rozhodně nebyla triviální a výrazně by se zvýšily hardwarové nároky.

Na Smalltalk je třeba nazírat jako na robustní vývojové prostředí, které je plně integrováno s vyvíjenou aplikací. Vývoj v konvenčních prostředích vypadá tak, že začnete svůj program budovat doslova od nuly. Postupně ho vytváříte a doplňujete o již hotové knihovny, komponenty apod. Smalltalk k problematice vývoje softwaru přistupuje naprosto obráceně. Na začátku je váš projekt obrovskou funkční aplikaci, která vám do značné míry slouží jako náhrada operačního systému s kompletním vývojový prostředím. Tato aplikace dokáže upravovat sama sebe, díky čemuž jste schopni ji přetvářet k obrazu svému. S možností využívat a v případě potřeby měnit libovolnou její část ji doplňujete o nové vlastnosti, přičemž ona je neustále funkční. Nemáte ani jinou možnost než s ní pracovat za jejího běhu. Vaše aplikace je živý organismus, jemuž máte neustále možnost prohrabávat střeva. Vaše aplikace je celý Smalltalk.

V okamžiku, kdy uznáte vaši aplikaci za hotovu, umí celou řadu věcí, které po ní ve skutečnosti nevyžadujete a mnohdy je ani nechcete. Nemáte třeba zájem na tom, aby ji uživatel mohl dále modifikovat, procházet si její zdrojové kódy. Prvním krokem, který je vhodné udělat, je odstranit z vaší aplikace vše, co pro svůj běh nepotřebuje. Odstraníte z image nepotřebné objekty a případně zacelíte vzniklé rány. Teoreticky sice může image dosahovat velikosti až několika málo stovek kilobytů, nicméně praxe je trochu jiná. U nejnovějších verzí image Squeaku jen s obtížemi dosáhnete velikosti pod 7 MB. Image netvoří zdaleka jen třídy a metody, obsahuje všechny objekty, tedy samozřejmě i fonty, různé grafické prvky apod.

Popravdě řečeno, co se týče ořezávání image o nepotřebné objekty, nenabízí v současnosti Squeak moc velký komfort a metody, které by tyto operace měly automatizovat (třída SystemDictionary, kategorie metod shrinking), jsou často šity na míru starším verzím Squeaku a nefungují korektně. Z tohoto pohledu je potěšitelné alespoň to, že od poslední stabilní verze (3.6) je kromě kompletní verze image (full) uvolňována i menší tzv. basic verze, ve které jsou některé specializované softwarové projekty vypuštěny. V přípravě je pak další minimální verze, která by měla obsahovat skutečně jen to nejnutnější. Jednotlivé balíčky je samozřejmě možno do image dohrávat samostatně.

Praxe je taková, že image pro Squeak se před nasazením často vůbec neořezává. Programátoři se prostě smíří s tím, že jejich aplikace je asi desetimegový bumbrlíček. Otázka je, jestli je to opravdu tak mnoho. Například pokud hledáte vývojový nástroj pro svou aplikaci, u které je nevyhnutelně nutné, aby byla snadno rozšiřitelná třeba pomocí pluginů při co největší jednoduchosti jak pro uživatele, tak pro vás jako autory, může pro vás být Squeak a jiné Smalltalky ideálním řešením. Když k tomu přičtete přenositelnost na všechny běžné platformy, možnost velmi snadné a nenáročné distribuce oprav (třeba přímo ve velmi kompaktní zdrojové formě) bez rekompilace či dodatečných nástrojů, podporu komprese, síťových protokolů a vůbec všeho, co Squeak nabízí, může výsledná velikost působit spíše směšně.

Pro specifické účely lze používat i starší verze Squeaku s image o velikostech kolem 2 MB. Jsou využívány například na kapesních počítačích, nicméně nové typy přístrojů typu PocketPC už nabízejí takový výkon a paměťový prostor, že bez problémů zvládají i nejnovější verze Squeaku včetně sources a changes. Kayova vize dynabook se tak po třiceti letech začíná pomalu naplňovat.

Samozřejmě ne vždy je vhodné, aby měli uživatelé naprosto neomezený přístup k vnitřnostem vaší aplikace. V takových případech se používá postup, který se označuje jako uzamčení image. Je to vlastně úplně stejný postup, jaký se provádí u jakékoliv jiné konvenčně napsané aplikace. Když nechcete, aby si s ní uživatel dělal, cokoliv ho napadne, nedáte mu žádnou možnost, jak by v ní mohl spouštět svůj vlastní kód – pravda, ne vždy se to (k radosti různých podvratných živlů) podaří.

Uzamčení image vypadá tak, že se uživateli zakáže používání vývojových prostředků, všemožných klávesových zkratek, spouštění skriptů při startu a podobně. Ve výsledku se pak smalltalkovská aplikace může tvářit jako jakákoliv jiná. Jak se takové uzamčení konkrétně provádí, se můžete dočíst například zde.

Pokud vytváříte programy v konvenčních jazycích, mohou společně využívat všemožné knihovny. Ty jsou pak většinou ve fyzické paměti jednotlivými aplikacemi sdíleny. Squeak v současnosti žádnou podobnou možnost sdílení částí image nemá.

Distribuce vaší aplikace jako celé image samozřejmě není jedinou možností, kterou máte k dispozici. Nejjednodušší formou exportu a importu zdrojových kódů z a do image jsou tzv. Goodies. Jsou to textové soubory s příponou *.st obsahující smalltalkovský kód. Když do nich nahlédnete, nelze si nevšimnout velkého množství vykřičníků v nich obsažených. Tyto vykřičníky oddělují části, které jsou překládány samostatně. Goodies představují to, jak by vypadal Smalltalk v případě, že by byl překládán ze zdrojového souboru tak, jak je tomu běžné u většiny programovacích jazyků. Nicméně takto se ve Smalltalku neprogramuje, používá se zásadně browser a jeho různé varianty, v nichž jsou zdrojové kódy uspořádány do přehledné stromové struktury. Na vi rovnou zapomeňte. Jedinou výjimku tvoří implementace Smalltalku bez grafického uživatelského rozhraní, jako je například GNU Smalltalk. Browser je možné otevřít i nad samostatnými Goodies.

K exportu a importu zdrojových kódů ve formě Goodies slouží operace „filein“ a „fileout“. Naleznete je v kontextových menu Squeaku na každém kroku, popřípadě v aplikaci File List. Vyfajlovat můžete jak jednotlivé metody, tak i kategorie metod, třídy a celé systémové kategorie.

Speciální verzí Goodies jsou tzv. ChangeSets (*.cs), které se nejčastěji používají ve spojitosti s projekty. Ve Squeaku si založíte nový projekt, čímž získáte čistou pracovní plochu připravenou pro práci. Procesy ostatních projektů jsou uspány. Každý projekt má vytvořenu vlastní množinu změn. Pokud programujete nové třídy a modifikujete již stávající, všechny změny jsou v této množině změn zaznamenávány a lze je následně jako celek prostřednictvím nástroje Change Sorter vyfajlovat. Příjemné je jejich automatické číslování. Importují se stejně jako ostatní Goodies.

Další možností je export celého projektu. Tímto způsobem se generují tzv. Squeaklety (*.pr). Ty kromě množin změn obsahují i části image s objekty v exportovaném projektu zahrnutými, což jsou například aktuálně otevřená okna nebo všemožná tlačítka, kresbičky a jiné tzv. morphy, se kterými ve svém projektu pracujete.

Mimo to má Squeak ještě vlastní balíčkovací systém, kterému se postupně svými schopnostmi daří přibližovat se linuxovým balíčkovacím systémům včetně podpory závislostí, verzování, updatování apod. Jednotlivé balíčky jsou publikovány na tzv. SqueakMap a nástroje pro jejich správu pracují samozřejmě přímo ve Squeaku.

CS24 tip temata

Navíc je možné provádět updaty vaší image na aktuální oficiální verzi přímo z Internetu. V tom případě jsou staženy nejnovější ChangeSety a automaticky za plného provozu nahrány do systému.

Na závěr ještě jednu poznámku k image. Pokud dostane VM příkaz k jejímu uložení, zapíše aktuální stav objektové paměti, tedy i aktuální běhový kontext. V okamžiku, kdy je opět nahrána, nachází se Smalltalk v naprosto stejném stavu jako při jejím uložení (na tyto události lze případně vhodně reagovat). To mimo jiné znamená, že od chvíle, kdy byl Smalltalk v roce 1977 spuštěn, neustále běží a sám sebe rozšiřuje a vylepšuje.