|
Syntax jazyka
Pseudo-proměnné
Pseudo-proměnné jsou rezervované identifikátory podobné klíčovým slovům z jiných jazyků
nil, true a false jsou konstanty
self, super a thisContext se dynamicky mění při běhu programu
Nad žádnou pseudo-proměnnou nelze použít přiřazení
| nil | jedinečná instance (jedináček, singleton) třídy UndefinedObject. Neinicializované objekty mají implicitně tuto hodnotu |
| true | jedinečná instance třídy True |
| false | jedinečná instance třídy False |
| self | reference na současný objekt, který je příjemcem zprávy. Obdoba „this“ z C++ |
| super | referencuje stejný objekt jako self, ovšem pokud je mu zaslána zpráva, začíná vyhledávání patřičné metody u předka třídy, v jejíž definici metody je užito slovo super. |
| ThisContext | aktivní kontext. Jedná se o v současnosti spuštěný MethodContext nebo BlockContext. |
Identifikátory
znak ( znak | číslice)
Identifikátory Smalltalku rozlišují malá a velká písmena (jsou case-sensitive)
Podle konvence Smalltalku začínají identifikátory malým písmenem a každé další významové slovo uvnitř identifikátoru začíná velkým písmenem (např. totoJeIdentifikátor)
Některé identifkátory, jako například globální proměnné (např. Smalltalk), jména tříd (což jsou také globlání proměnné) a třídní proměnné začínají z konvence na velká písmena.
Komentáře
"Komentáře jsou vkládány do uvozovek"
"Komentáře mohou obsahovat 'apostrofy', které uvozují řetězcové konstanty"
"Komentáře mohou obsahovat vnořené uvozovky "" pomocí jejich zdvojení"
"""""" - toto je komentář obsahující dvě uvozovky
"Komentáře mohou být rozděleny na mnoho,
mnoho
řádků"
Literály (konstantní výrazy)
Čísla (instance třídy Number)
Desítkové číslice: 1234, 1234657890123456789
Osmičkové číslice: 8r177, 8r1777777777777777
Šestnáctkové číslice: 16rFF, 16r1234567890ABCDEF
Dvojkové číslice: 2r1010 (10)
Celé číslice s exponentem: 123e2 (12300), 2r1010e2 (40)
Reálná čísla: 3.14e-10
Binární reálná čísla: 2r1.1 (1.5), 2r1.1e2 (60)
Squeak podporuje aritmetiku SmallInteger (celá čísla v rozsahu -230 až 230-1) pomocí rychlých interních primitiv.
Squeak podporuje libovolnou přesnost aritmetických výpočtů pomocí automatické konverze SmallInteger na LargePositiveInteger a LargeNegativeInteger, což má však přirozeně vliv na výkon.
Squeak podporuje několik dalších druhů numerických hodnot, jako jsou například zlomky (Fraction, např. 2/3) a body (Point např. 2@3).
Zatímco pro ně neexistují literály, jsou přirozeně vyjádřeny jako operace nad vestavěnými literály.
Základ soustavy je vždy vyjádřen desítkově.
Znaky (instance třídy Character)
$x - předchází je znak dolaru
$3 - toto je rovněž znak – pro číslici tři
$< - nebo pro symbol "menší než"
$$ - znak pro znak dolaru
Řetězce (instance třídy String)
'řetězec je uvozen apostrofy'
'řetězec může obsahovat “uvozovky používané pro komentáře“'
'řetězce mohou obsahovat apostrofy '' vyjádřené jejich zdvojením
'řetězce mohou obsahovat vložené
znaky pro nový řádek'
'' a nesmíme zapomenout na prázdný řetězec
Řetězce jsou velmi podobné polím obsahujícím znaky. Indexujeme je od jedničky.
Symboly (instance třídy Symbol)
#'řetězec uvozený znakem mřížky (hash) je Symbol'
#neboNejakyIdentifikatorUvozenyMrizkou
#neboIdentifikátorUkoncenyDvouteckou:
#neboNekolik:identifikatoru:oddelenych:dvouteckou:
#- symbol může být také mřížka následovaná nějakým speciálním symbolem
#-< nebo párem speciálních symbolů
Symbol je podtřída třídy String a rozumí velké části stejných zpráv
Hlavní rozdíl mezi symbolem a řetězcem je v tom, že všechny symboly obsahující stejnou sekvecni znaků mají jednu společnou instanci.
Řetězce mohou mít sice naprosto stejný obsah, ovšem různé instance.
To znamená, že Symboly mohou být účinně porovnávány, protože rovnost (=) je u nich to samé jako identita (==)
Identifikátory s dvojtečkou (např. #selektor:klíčového:slova) jsou často použity jako selektory klíčových slov
Jednoduchý nebo dvojitý symbol (např. # nebo #++) jsou často používány jako binární selektory
Přípustné jsou jsou následující speciální znaky: +/~<=>@%|&?!
Poznamenejme, že #-- není symbol (nebo binární selektor). Na druhou stranu #'--' je symbol (ovšem nikoliv binární selektor)
Konstantní pole (instance třídy Array)
#( 1 2 3 4 5 ) je bole velikosti 5 obsahující čísla 1 až 5
#('this' #is $a #'constant' array ) toto je pole velikosti pět obsahující řetězec, symbol #is, znak a dva symboly #constant a #array
#( 1 2 (1 #(2) 3 ) 4) je pole velikosti 4 obsahující dvě čísla, pole velikosti tři a další číslo
#(1 + 2) je pole velikosti tři obsahující číslo 1, symbol #+ a číslo 2. NENÍ to pole obsahující číslo 3!
Přiřazení
identifikátor _ výraz
identifikátor := výraz
neco := 100 factorial
neco := necoDalsiho := 100 factorial
Identifikátory (proměnné, třídní proměnné, dočasné proměnné apod.) budou po přiřazení odkazovat na objekty dodané jako výsledek výrazu
Pro přiřazení se standardně používal znak šipky. Ten se nahrazuje pomocí podtržítka _
Přiřazení jsou výrazy a mohou se vyskytovat v kaskádě
Zprávy
Unární zprávy (unary messages)
theta sin
quantity sqrt
nameString size
1.5tan rounded asStrig "stejný výsledek jako (((1.5 tan) rounded) asString)"
Unární zprávy jsou zprávy bez argumentů
Jsou vyhodnoceny jako první a to vždy zleva doprava
Binární zprávy (binary messages)
3+4 "=7, trojce je poslána zpráva se selektorem #+ argumentem čtyři"
3+45 "=35, nikoliv 23"
3+4 factorial "=27, nikoliv 5040"
total – 1
celkem = max "=true, jestliže celkem je menší nebo rovno max"
(4/3)3 = 4 "=true, rovnost je binární zpráva a zlomky jsou přesné, nepodléhají zaokrouhlení"
(4/3) == (4/3) "=false, zlomky jsou stejné, ale nejsou to stejné objekty, zpráva #== je identita"
Binární zprávy mají příjemce na levé straně a jeden argument (pravá strana).
Binární zprávy jsou vždy vyhodnocovány zleva doprava, bez ohledu na priority numerických operací, je třeba používat závorky
Jsou vyhodnoceny po unárních zprávách
Slovní zprávy (keyword messages)
12 between: 8 and: 15 "=true"
#($t $e $s $t) at: 3 "=$s"
array at: index put: value
array at: index factorial put: value
1 to: 3 do: aBlock "zašle zprávu #to:do: se dvěma parametry číslu 1"
(1to: 3) do: aBlock "zašle zprávu #do: s jedním parametrem intervalu (Interval) danému vyhodnocením '1 to: 3'"
Slovní zprávy mají jeden nebo více argumentů
Jsou vyhodnoceny jako poslední
Sekvence výrazů
sekvecneVyrazu := vyraz (.vyraz) (.)opt
box := 20@30 corner: 60@90.
box containsPoint: 40@30
Výrazy jsou odděleny tečkou a jsou vyhodnoceny sekvenčně.
Výsledek sekvence výrazů je roven výsledku posledního výrazu.
Výsledky ostatních výrazů jsou ignorovány.
Poslední tečka je volitelná.
Kaskáda (cascade expressions)
Transcript show: 'Hello world!'; cr; show: 'next line'.
receiver unaryMessage; +23; at:23 put: value; yourself.
Set new add: x; add: y; yourself.
Zprávy v kaskádě jsou odděleny středníky, všechny jsou zaslány příjemci sekvence (receiver)
Průběžné výsledky jsou ignorovány (krom jejich vedlejších efektů)
Kaskáda odpovídá výsledku vyhodnocení poslední zprávy (po zaslání všech předchozích)
Bloky (block expressions)
Bloky jsou ve skutečnosti instance třídy BlockContext. Jsou používány pro tvorbu řídících struktur.
Vytváří se pomocí hranatých závorek [ ] ohraničujících sekvenci výrazů
[ sekvenceVyrazu ] "blok bez argumentů"
[ (:identifikator)+ | sekvenceVyrazu ] "blok s argumenty"
[ (:identifikator)+ | | identifikator | sekvenceVyrazu ] "blok s argumenty a lokálními proměnnými"
[ 1. 2. 3 ] "blok, jenž po vyhodnocení odpovídá hodnotě 3"
[:parametr | parametr delejNeco ] “blok s jedním parametrem, jemuž se zašle zpráva #delejNeco“
Blok zapouzdřuje sekvenci akcí
Blok vyhodnotíme zasláním zprávy #value
[ 1. 2. 3. ] "= nedefinovaný objekt"
[ 1. 2. 3. ] value "=3"
Vyhodnocovací výrazy bloků
| value | vyhodnotí blok |
| value: arg | vyhodnotí blok s argumentem arg. |
| valueWithArguments: anArray | vyhodnotí blok s argumenty uloženými v poli anArray. Je prováděna kontrola očekávaného počtu argumentů vyhodnocovaného bloku a velikosti pole argumentů. |
Bloky ve Squeaku také rozumí zprávám #value:value:, #value:value:value a #value:value:value:value:.
Větší počet argumentů musí být předáván v poli pomocí zprávy #valueWithArguments:
Řídící struktury
Výrazová pole
VyrazovePole ::= { SekvenceVyrazu }
{ 1. 2. 3. 4. 5 } "Pole velikosti pět obsahující pět celých čísel 1-5"
{ $a. #brace. array } "Pole velikosti tři obsahující znak $a, symbol #brace a současnou hodnotu proměnné array"
{ 1 + 2 } "Pole velikosti jedna obsahující jedno celé číslo 3"
Výrazová pole jsou sekvence výrazů vyhodnocovaných za běhu programu
Prvky výrazového pole jsou výsledky jednotlivých výrazů, z nichž se skládá
Mnohdy jsou vhodnější a více obecnou variantou výrazzu Array with expr1 with: expr2 with: expr3
Jsou indexována od jedničky
Návratové výrazy
navratovyVyraz ::= ^vyraz
^docasnaPromenna
^2+3
Uvnitř těla metody je návratový výraz užit k ukončení provádění dané metody a předání návratové hodnoty, jenž je rovna výsledku výrazu
Návratové výrazy uvnitř vnořeného bloku ukončí celou obalující metodu, nikoliv pouze vyhodnocování vnoženého bloku
Alternativy (příjemce je Boolean)
| ifTrue: aBlock | odpovídá nil, pokud příjemce je false, jinak vyhodnotí aBlock |
| ifFalse: aBlock | odpovídá nil, pokud příjemce je true, jinak vyhodnotí aBlock |
| ifTrue: aTrueBlock ifFalse: aFalseBlock | odpovídá objektu aTrueBlock value, pokud příjemce je true. Odovídá objektu aFalseBlock value, pokud příjemce je false |
| ifFasle aFalseBlock ifTrue: aTrueBlock | obdoba #ifTrue:ifFalse |
Technicky se nejedná o řídící struktury, mohou být chápány jako slovní zprávy, jež jsou zasílány objektům typu Boolean (viz definice těchto metody ve třídách True a False), nicméně hrají stejnou úlohu jako kontrolní struktury v jiných jazycích
Překlad některých řídících struktur do bytekódu Smalltalku je optimalizován, takže jejich provádění není realizováno voláním metod.
Alternativy (příjemce je Object)
| ifNil: nilBlock | výsledek odpovídá objektu nilBlock value, pokud příjemce je nil. Jinak odpovídá příjemci. |
| ifNotNil: notNilBlock | výsledek odpovídá objektu nilBlock value, pokud příjemce není nil. Jinak odpovídá příjemci. |
| ifNil: nilBlock ifNotNil: notNilBlock | spojení předešlého |
| ifNotNil: notNilBlock ifNil: nilBlock | obdoba #ifNil:ifNotNil |
Iterativní řídící struktury (příjemce je BlockContext)
| whileTrue | vyhodnocuje příjemce tak dlouho, dokud jeho hodnota je true |
| whileTrue: aBlock | vyhodnotí příjemce, jestliže je true, vyhodnotí aBlock a celé opakuje |
| whileFalse | obdoba #whileTrue |
| whileFalse: aBlock | obdoba #whileTrue: |
Vyhodnocovací řídící struktury (příjemce je Integer)
| timesRepeat: aBlock | provede aBlock n-krát, kde n je hodnota příjemce. |
| to: stop do: aBlock | vyhodnotí aBlok s každým elementem intervalu (self to: stop by: 1) jako argumentem |
| to: stop by: step do: aBlock | vyhodnotí aBlok s každým elementem intervalu (self to: stop by: step) jako argumentem |
Vyhodnocovací řídící struktury (příjemce je Collection)
| do:aBlock | pro každý prvek příjemce vyhodnoť aBlock s tímto prvkem jako argumentem |
Výběr (příjemce je Object)
| caseOf: aBlockAssociationCollection | Odpovídá vyhodnocení první asociace v aBockAssociationCollection, jejíž vyhodnocený klíč je roven příjemci. Pokud není nalezena shoda, je zaslán signál Error |
| caseOf: aBlockAssociationCollection otherwise: aBlock | Odpovídá vyhodnocení první asociace v aBockAssociationCollection, jejíž vyhodnocený klíč je roven příjemci. Pokud není nalezena shoda, je vrácen výledek vyhodnocení bloku aBlock |
aBlockAssociationCollection je kolekce asociací (Association) - párů klíč/hodnota.
aSymbol caseOf: {
[#a]->[1+1].
['b' asSymbol]->[2+2].
[#c]->[3+3]
}
Definice tříd
Běžná definice třídy
SuperClass subclass: #NameOfClass
instanceVariableNames: 'instVarName1 instVarName2'
classVariableNames: 'ClassVarName1 ClassVarName2'
poolDictionaries: ''
category: 'Major-Minor'
Definice proměnných tříd
Tato forma definice se používá pro vytváření indexovatelných objektů jako např. Array ByteArray a WorldArray. Nejsou běžně používány přímo, používejte běžné definice objektů, jejichž instanční proměnná je Array či jiná kolekce
SuperClass variableSubclass: #NameOfClass
instanceVariableNames: 'instVarName1 instVarName2'
classVariableNames: 'ClassVarName1 ClassVarName2'
poolDictionaries: ''
category: 'Major-Minor'
SuperClass variableByteSubclass: #NameOfClass
instanceVariableNames: 'instVarName1 instVarName2'
classVariableNames: 'ClassVarName1 ClassVarName2'
poolDictionaries: ''
category: 'Major-Minor'
SuperClass variableWordSubclass: #NameOfClass
instanceVariableNames: 'instVarName1 instVarName2'
classVariableNames: 'ClassVarName1 ClassVarName2'
poolDictionaries: ''
category: 'Major-Minor'
Definice metod
Všechny metody vrací hodnotu. Implicitní je ^self. Na konci každé metody se ujistětě, zda se jedná zrovna o váš případ.
lineCount
"Answer the number of lines represented by the receiver,
where every cr adds one line."
| cr count |
cr := Character cr.
count := 1 min: self size.
self do:
[:c | c == cr ifTrue: [count := count + 1]].
^ count
Odkaz na tuto stránku
- Články, poslední úprava dne 12 Srpen 2010 v 12:21:53 uživatelem localhost
|