Obsah
2. Umístění objektů na pracovní plochu Squeaku
5. Pořadí vyhodnocování unárních a binárních zpráv
6. Zprávy s obecným počtem parametrů
7. Nejčastější problémy při zápisu zpráv s obecným počtem parametrů
1. Unární zprávy
V předchozí části článku o programovacím jazyce Squeak jsme se již ve stručnosti zmínili o tom, že objekty (ať již se jedná o objekty vytvořené uživatelem či o systémové objekty, které například reprezentují prvky grafického uživatelského rozhraní) mezi sebou komunikují pomocí takzvaného „posílání zpráv“ a taktéž to, že ve Squeaku existují tři typy zpráv, které se od sebe odlišují především syntakticky, tj. způsobem zápisu. Jedná se o unární zprávy, binární zprávy a o zprávy s obecným počtem parametrů. Nejdříve se budeme zabývat unárními zprávami, protože práce s nimi je nejjednodušší. Unární zprávy poslané nějakému objektu neobsahují žádný parametr, objekt se tedy rozhoduje, jakým způsobem má na poslanou zprávu zareagovat, přímo podle toho, o jakou zprávu se jedná, tj. na základě jejího selektoru (zjednodušeně řečeno: podle toho jaké má zpráva jméno). Proč se však těmto zprávám říká „unární“? Je tomu tak z toho důvodu, že se při poslání tohoto typu zprávy pracuje pouze s jediným objektem – příjemcem zprávy.
Formát zápisu unárních zpráv je ze syntaktického hlediska velmi jednoduchý: selektor zprávy se zapíše přímo za jméno objektu (příjemce zprávy), jak je to ostatně patrné z následujících demonstračních příkladů. Poznámka: na prvním řádku ve výpisu je vždy uveden výraz zapsaný uživatelem, na řádku druhém objekt, který vznikl na základě reakce příjemce zprávy. Příklady je možné si vyzkoušet například v okně Workspace popsaném v předchozích dvou částech tohoto seriálu (po zapsání výrazu postačuje stlačit klávesovou zkratku CTRL+p, popř. z kontextového menu vybrat příkaz print it, aby došlo k vytištění výsledného objektu, resp. textové reprezentace tohoto objektu do okna Workspace):
42 factorial 1405006117752879898543142606244511569936384000000000
1405006117752879898543142606244511569936384000000000 digitLength 22
-42 abs 42
42 threeDigitName 'forty-two'
'www.root.cz' stringhash 157059795
true not false
false not true
Obrázek 1: Okno Workspace, v němž je možné jednoduše posílat zprávy různým objektům a vypisovat textové reprezentace objektů, které vzniknou na základě těchto zpráv.
Pokud příjemce zprávy nedokáže unární zprávu s daným selektorem zpracovat, dojde k chybě:
'www.root.cz' abs " na tomto místě dojde k zahlášení chyby," " protože objekt 'www.root.cz' (tj. řetězec)" " nedokáže zareagovat na zprávu se selektorem abs."
Obrázek 2: Výsledek pokusu o poslání zprávy se selektorem abs řetězci, který na tuto zprávu nedokáže korektně zareagovat. Z vypsaného chybového hlášení je patrné, že instance třídy ByteString nezná metodu abs.
2. Umístění objektů na pracovní plochu Sqeaku
Výsledkem poslání unární zprávy může být dokonce i objekt, který se stane součástí grafického uživatelského rozhraní Squeaku, například bude umístěn na jeho pracovní ploše. Bez dalšího podrobnějšího popisu (k němu se však v tomto seriálu později ještě několikrát vrátíme) si můžete sami vyzkoušet následující demonstrační příklad. Po poslání zprávy se selektorem openAsMorph objektu (příjemci zprávy), jenž je instancí třídy String nebo některého jejího potomka, například ByteString, se na pracovní plochu do určeného místa umístí nový prvek grafického uživatelského rozhraní, s nímž je možné libovolným způsobem manipulovat, podobně jako s jakýmkoli jiným prvkem GUI Squeaku. Lze například provést přesun tohoto objektu, jeho zvětšení, zmenšení, otáčení, vytvoření kopie (klonu) atd. Tento objekt samozřejmě „přežije“ i ukončení virtuálního stroje a jeho opětovné nastartování, a to dokonce i v případě, že je znovuspuštění virtuálního stroje provedeno na zcela odlišné platformě:
'maly testik' openAsMorph
Obrázek 3: Poslání zprávy se selektorem openAsMorph řetězci. Ihned po poslání zprávy se vytvoří nový prvek grafického uživatelského rozhraní, který lze umístit pomocí myši na pracovní plochu.
Obrázek 4: S objektem umístěným na pracovní plochu lze manipulovat stejným způsobem, jako s jakýmkoli jiným objektem, například oknem. K objektu je samozřejmě také přiřazené kontextové menu i „obrázkové“ menu.
3. Zřetězení unárních zpráv
Vzhledem k tomu, že výsledkem poslání zprávy jejímu příjemci je vznik (většinou nového) objektu, je možné zprávy za sebou jednoduše zřetězit bez toho, aby se mezivýsledné objekty vzniklé voláním zpráv musely ukládat do pojmenovaných proměnných. Syntakticky se zřetězení zpráv podobá například volání uživatelských nebo systémových slov ve Forthu, ale to již trošku odbíháme od tématu. V následujícím demonstračním příkladu se nejdříve pošle zpráva se selektorem factorial příjemci, jenž je malým celým číslem (SmallInteger) a tento objekt zprávu zpracuje takovým způsobem, že vytvoří nový objekt (poněkud větší číslo, konkrétně instanci třídy LargePositiveInteger). Tomuto objektu je následně poslána unární zpráva se selektorem asWords. Příjemce tuto zprávu zpracuje a jako výsledek vrátí řetězec (což je samozřejmě taktéž objekt), který obsahuje slovní vyjádření vypočtené hodnoty (kvůli omezení šířky stránky v prohlížeči jsou do výsledku přidány konce řádků):
42 factorial asWords 'one sexdecillion, four hundred five quindecillion, six quattuordecillion, one hundred seventeen tredecillion, seven hundred fifty-two duodecillion, eight hundred seventy-nine undecillion, eight hundred ninety-eight decillion, five hundred forty-three nonillion, one hundred forty-two octillion, six hundred six septillion, two hundred forty-four sextillion, five hundred eleven quintillion, five hundred sixty-nine quadrillion, nine hundred thirty-six trillion, three hundred eighty-four billion'
Obrázek 5: Poslání unární zprávy se selektorem className různým typům objektů.
V předchozím odstavci jsem bez dalších důkazů tvrdil, že objekt 42 je instancí třídy SmallInteger, zatímco výsledek zprávy 42 factorial je instancí třídy LargePositiveInteger. Toto tvrzení lze velmi jednoduše dokázat, protože každému objektu je možné poslat unární zprávu se selektorem className a objekt (příjemce zprávy) vrátí textovou reprezentaci jména příslušné třídy:
42 className 'SmallInteger'
42 factorial className 'LargePositiveInteger'
'www.root.cz' className 'ByteString'
nil className 'UndefinedObject'
Obrázek 6: Metoda className existuje již ve třídě Object, proto ji dědí i všechny uživatelem vytvořené objekty.
Podobným způsobem se lze pomocí zprávy se selektorem basicType dotazovat na bázový typ objektu (výsledkem je v tomto případě symbol, nikoli řetězec):
42 basicType #Number
true basicType #Boolean
'www.root.cz' basicType #String
nil basicType #Object
4. Binární zprávy
Druhým typem zpráv, které je možné ve Squeaku použít, jsou takzvané binární zprávy. Jak již název těchto zpráv naznačuje, tyto zprávy pracují s dvojicí objektů. Prvním objektem je příjemce zprávy. Podobně jako u unárních zpráv se jedná o objekt, který zprávu musí přijmout a zpracovat; právě tento objekt tedy rozhoduje o tom, jak bude se zprávou naloženo (to může být zpočátku poněkud matoucí, protože binární zprávy se podobají, jak si ukážeme dále, zápisu aritmetických či logických výrazů, v nichž mají oba operandy binární operace shodný význam). Druhý objekt je použit jako parametr zprávy. Formát zápisu binárních zpráv vypadá následovně: příjemce_zprávy selektor parametr. Zatímco unární zprávy mohly mít takřka libovolně pojmenovaný selektor (nemohly v něm být použity pouze některé znaky se speciálním významem), jména (selektory) binárních zpráv jsou ve Squeaku a taktéž i v dalších dialektech Smalltalku omezena pouze na některé znaky a jejich kombinace, které jsou vypsány v následující tabulce:
Znak |
---|
+ |
– |
* |
/ |
\ |
~ |
< |
> |
= |
@ |
% |
| |
& |
? |
, |
Následují demonstrační příklady poslání binárních zpráv různým typům objektů. Z toho, že každý objekt může na zprávu se stejným selektorem reagovat různě taktéž vyplývá, že není žádný problém si některé ze selektorů binárních zpráv „přetížit“ ve vlastních třídách:
6 * 7 42
123456 \\ 78 60
true & false false
true | false true
Ve třídě Boolean můžeme nalézt metodu pro výpočet logické operace implikace zapisované pomocí znaků ==>:
false ==> false true
false ==> true true
true ==> false false
true ==> true true
Řetězce, tj. instance třídy String nebo některého potomka této třídy, lze lexikograficky porovnávat:
'www' < 'aaa' false
'aaa' < 'www' true
'aaa' == 'www' false
'aaa' == 'aaa' true
Obrázek 7: Posílání binárních zpráv různým typům objektů.
5. Pořadí vyhodnocování unárních a binárních zpráv
Podobně jako je možné řetězit unární zprávy (viz třetí kapitola), lze v jednom výrazu kombinovat zprávy unární i binární. Přitom vždy platí, že unární zprávy jsou vyhodnoceny nejdříve (zjednodušeně by se dalo říci, že jsou okolo nich vytvořeny implicitní závorky) a binární zprávy se vyhodnocují zleva doprava, bez ohledu na to, že se znaky používané jako selektory binárních zpráv podobají aritmetickým či logickým operacím, jenž mají rozdílnou prioritu (násobení má vyšší prioritu než sčítání atd.). V případě, že je zapotřebí změnit pořadí volání zpráv, lze pro tento účel použít kulaté závorky. V následujících příkladech je ukázán rozdíl mezi běžnými aritmetickými výrazy (které ve skutečnosti Squeak vůbec nezná a v podstatě ani znát nepotřebuje) a voláním binárních zpráv, popř. kombinace zpráv unárních a binárních. Povšimněte si především toho, že v prvních několika výrazech není brána v potaz priorita binárních zpráv, které se vyhodnotí, tj. postupně zavolají tak, jak jsou zapsány – zleva doprava:
2 + 4 * 10 60
(2 + 4) * 10 60
2 + (4 * 10) 42
2 + 3 factorial 8
(2 + 3) factorial 120
3 factorial + 2 8
Obrázek 8: Výsledek volání různých kombinací unárních a binárních zpráv.
Ve chvíli, kdy zapomeneme na to, že ve Squeaku neexistují aritmetické a logické operace, ale „pouze“ posílání zpráv s pevně daným pořadím vyhodnocování, můžeme v programu použít zdánlivě korektní výraz, který však ve skutečnosti povede k chybě. Jeden z typických chybně zapsaných výrazů je například: 42 == 2 + (4 * 10). Tento zápis totiž znamená poslání zprávy se selektorem ==, jejímž příjemcem je objekt 42 a parametrem objekt 2. Výsledkem je objekt false, který je příjemcem zprávy se selektorem +… – a právě zde dojde k chybě, protože objekt false nedokáže na tuto zprávu korektně zareagovat. Náprava je snadná – buď je možné prohodit pořadí zpráv nebo lze použít závorky:
42 == 2 + (4 * 10) " chyba - objekt typu Boolean nedokáže zpracovat zprávu se selektorem + "
2 + (4 * 10) == 42 true
42 == (2 + (4 * 10)) true
Obrázek 9: Výsledek pokusu o vyhodnocení výrazu 42 == 2 + (4 * 10).
6. Zprávy s obecným počtem parametrů
Třetím a současně i posledním typem zpráv, pomocí nichž mohou objekty ve Squeaku (nebo i jiném dialektu programovacího jazyka Smalltalk) navzájem komunikovat, jsou zprávy s proměnným počtem parametrů, někdy také nazývané keyword messages. V těchto zprávách může být použito libovolné množství klíčových slov ukončených dvojtečkou, přičemž za každým klíčovým slovem následuje parametr. To mj. znamená, že počet parametrů zprávy odpovídá počtu použitých klíčových slov. Selektorem těchto zpráv jsou všechna klíčová slova. Tento typ zpráv má nejnižší prioritu, což znamená, že nejdříve jsou vyhodnoceny zprávy unární, posléze zprávy binární a teprve poté zprávy s proměnným počtem parametrů (samozřejmě je možné v případě potřeby použít závorky, které pořadí volání zpráv mění). Porovnání syntaxe binární zprávy (popsané v předchozích kapitolách) a zprávy s proměnným počtem parametrů je zobrazeno na desátém obrázku.
Obrázek 10: Syntaxe binární zprávy a zprávy s proměnným počtem parametrů.
Příklady zpráv používajících klíčová slova:
42 gcd: 123456 6
1024 log: 2 10.0
42 raisedTo: 42 150130937545296572356771972164254457814047970568738777235893533016064
42 between: 0 and: 100 true
42 between: 100 and: 200 false
V posledních dvou příkladech je between:and: metoda definovaná ve třídě Magnitude, která je předkem tříd Integer a SmallInteger.
7. Nejčastější problémy při zápisu zpráv s obecným počtem parametrů
Při používání zpráv s proměnným počtem parametrů je nutné si uvědomit, že se příjemci zprávy skutečně posílá celá zpráva, jejíž selektor je složen ze všech klíčových slov a počet parametrů odpovídá počtu těchto slov. To například znamená, že následující zápis:
2 raisedTo: 3 raisedTo: 4
Squeak pochopí tak, že se objektu 2 (tj. instanci třídy SmallInteger) posílá zpráva se selektorem raisedTo:raisedTo: a s parametry 3 a 4; tudíž dojde při pokusu o vyhodnocení tohoto výrazu k chybě, pokud si tedy sami nerozšíříme chování třídy SmallInteger takovým způsobem, aby dokázala tuto zprávu korektně zpracovat. Náprava je v tomto případě jednoduchá – v závislosti na tom, jakou aritmetickou operaci máme skutečně na mysli (zda 2(34) nebo (23)4), je nutné použít uzávorkování:
2 raisedTo: (3 raisedTo: 4) 2417851639229258349412352
(2 raisedTo: 3) raisedTo: 4 4096
8. Programové bloky
Poslední vlastností Squeaku, o které se dnes zmíníme, je podpora takzvaných programových bloků, bez nichž by například nebylo možné tvořit programové smyčky ani struktury s podmínkami (tyto řídicí struktury ve Squeaku neexistují jako samostatná syntaktická kategorie právě díky tomu, že se dají nahradit pomocí bloků). Programové bloky se skládají z nepovinných parametrů následovaných posloupností výrazů. Ze sémantického hlediska se programový blok chová jako uzávěr (closure), který je (ve Squeaku) považován za plnohodnotný objekt. To mj. znamená, že bloku lze posílat různé zprávy a blok může vystupovat jako parametr zpráv, což je v mnoha případech důležitější vlastnost. Z hlediska syntaktického je blok uzavřen do hranatých závorek [] a jeho případné parametry jsou od těla bloku (seznamu výrazů) odděleny pomocí znaku roury (pipe, |). Pokud blok žádné parametry nemá, není použit ani oddělovač. Následuje příklad jednoduchého bloku bez parametrů:
[ 6 * 7 ]
Jak jsme si již řekli v předchozím odstavci, lze blokům posílat zprávy. V následujících příkladech je ukázáno, jak lze blok vyhodnotit (zavolat výrazy, které se v jeho těle nachází), jak lze zjistit, kolikrát se blok vyhodnotí za 5 sekund (jednoduchý benchmark), jak dlouho trvá jedno vyhodnocení bloku (v tomto případě prakticky neměřitelné) a jak lze vytvořit nekonečnou smyčku (prakticky měřitelné :-)
[ 6 * 7 ] value 42
[ 6 * 7 ] bench '722571.4857028595 per second.'
[ 6 * 7 ] durationToRun 0:00:00:00
[ 6 * 7 ] repeat " není dobrý nápad tento kód spouštět, protože blok" " neobsahuje explicitiní příkaz pro jeho zastavení"
Programový blok může vystupovat jako parametr nějaké zprávy, čehož se poměrně často využívá například při programování smyček nebo struktur s podmínkami. Na následujících příkladech je ukázáno, jak lze využít zprávy se selektorem ifTrue: a ifFalse:, které jsou implementovány jako metody ve třídách Boolean, True a False, pro tvorbu části kódu, jenž se provede pouze v případě splnění či naopak nesplnění nějaké podmínky:
true ifFalse: [ 6 * 7 ] nil
false ifFalse: [ 6 * 7 ] 42
1 == 1 ifFalse: [ 6 * 7 ] nil
1 == 2 ifFalse: [ 6 * 7 ] 42
true ifTrue: [ 6 * 7 ] 42
false ifTrue: [ 6 * 7 ] nil
1 == 1 ifTrue: [ 6 * 7 ] 42
1 == 2 ifTrue: [ 6 * 7 ] nil
Podrobnější informace o použití bloků, které tvoří jednu z nejzajímavějších částí Squeaku, si uvedeme příště.
9. Odkazy na Internetu
- Squeak home page
http://www.squeak.org/ - XO: The Children's Machine
http://wiki.laptop.org/go/The_Children's_Machine - Squeak na Wikipedii EN
http://en.wikipedia.org/wiki/Squeak - Squeak na Wikipedii CZ
http://cs.wikipedia.org/wiki/Squeak - Squeak by Example
http://squeakbyexample.org/ - Squeak Land
http://www.squeakland.org/ - SqueakNotes
http://squeak.zwiki.org/SqueakNotes - Squeak FAQ
http://wiki.squeak.org/squeak/471 - Learning Squeak
http://c2.com/cgi/wiki?LearningSqueak - Scratch home page
http://scratch.mit.edu/ - Scratch (programming language)
http://en.wikipedia.org/wiki/Scratch_(programming_language) - Lazarus (Software)
http://en.wikipedia.org/wiki/Lazarus_%28software%29 - FreePascal
http://www.freepascal.org/ - „Why I Love Python“ slides
http://www.mindviewinc.com/downloads/pub/eckel/LovePython.zip - „Why I love Python“ (presentation)
http://www.slideshare.net/didip/why-i-love-python - První jazyk: Python
http://macek.sandbox.cz/texty/prvni-jazyk-python/ - Programovací jazyk Python
http://www.py.cz/FrontPage - Python – Wikipedia CS
http://cs.wikipedia.org/wiki/Python - IPython
http://en.wikipedia.org/wiki/Ipython - IPython: an interactive computing environment
http://ipython.scipy.org/moin/ - Category:Python
http://rosettacode.org/wiki/Category:Python - Educational programming language
http://en.wikipedia.org/wiki/Educational_programming_language - Seriál Letní škola programovacího jazyka Logo
http://www.root.cz/serialy/letni-skola-programovaciho-jazyka-logo/ - Logo Tree Project:
http://www.elica.net/download/papers/LogoTreeProject.pdf - Language Poster (O'Reilly):
http://www.oreilly.com/news/graphics/prog_lang_poster.pdf - Informace o Comenius Logu:
http://www.comlogo.input.sk/index.html - Stránka nabízející stažení Comenius Loga:
http://www.comlogo.input.sk/nastiahnutie.html - Seminární práce o Comenius Logu:
http://nwit.pedf.cuni.cz/rotal9ap/logo/ - Informace o LEGO/Logu:
http://education.otago.ac.nz/nzlnet/Logo/legologo.html - Informace o systému Elica:
http://www.elica.net/site/index.html - Informace o systému NetLogo:
http://ccl.northwestern.edu/netlogo/ - Stažení NetLoga:
http://ccl.northwestern.edu/netlogo/download.shtml - Uživatelský manuál NetLoga ve formátu PDF:
http://ccl.northwestern.edu/netlogo/docs/NetLogo%20User%20Manual.pdf - NetLogo FAQ:
http://ccl.northwestern.edu/netlogo/docs/faq.html - Domácí stránka Daniela Azumy (autora implementace Turtle Tracks):
http://alumnus.caltech.edu/~dazuma/home/ - Informace o aUCBLogu:
http://www.physik.uni-augsburg.de/~micheler/ - Domácí stránka MSW Loga:
http://www.softronix.com/logo.html - Karel online
http://karel.oldium.net/ - EDU-SIG: Python in Education
http://www.python.org/community/sigs/current/edu-sig/ - Guido van Robot
http://en.wikipedia.org/wiki/Guido_van_Robot - The Guido van Robot Programming Language
http://gvr.sourceforge.net/ - An Introduction to Programming with Karel J. Robot
http://blog.thingoid.com/2003/10/karel-intro/ - Teaching a young robot new tricks
http://blog.thingoid.com/2003/11/karel-new-tricks/ - Karel and Company – More Robots
http://blog.thingoid.com/2003/12/karel-and-company/ - Karel heads for the stars
http://blog.thingoid.com/2004/03/karel-star/ - Karel programming language documentation
http://mormegil.wz.cz/prog/karel/prog_doc.htm - Karel J. Robot
http://www.mainlandregional.net/dklipp/Honors%20Computer%20Science%20Java.htm - Karel (programming language)
http://en.wikipedia.org/wiki/Karel_(programming_language) - Richard E. Pattis
http://en.wikipedia.org/wiki/Richard_E._Pattis - XKarel home page
http://xkarel.sourceforge.net/eng/ - XKarel – screenshoty oken
http://xkarel.sourceforge.net/eng/program.php#Okna - Greenfoot
http://www.greenfoot.org/about/whatis.html - Computer programming – Educational programming languages
http://www.kidslike.info/computer_programming_educational_programming_languages - Making Great Programmers: Why BASIC is Still Relevant
http://kidbasic.sourceforge.net/en/why.html - Gambas Wiki
http://en.wikibooks.org/wiki/Gambas - Free tool offers ‚easy‘ coding
http://news.bbc.co.uk/2/hi/technology/6647011.stm - Scratch Lowers Resistance to Programming
http://www.wired.com/gadgetlab/2009/03/scratch-lowers/ - Základy želví grafiky
http://www.root.cz/clanky/zaklady-zelvi-grafiky/ - Bill Kendrick's Web Turtle
http://www.sonic.net/~nbs/webturtle/