Squak Smalltalk [6 * 9 = 42] whileTrue: [World run]
Stopařův průvodce jedním převážně neškodným programovacím jazykem
smalltalk
Swiki
  • Domů
  • Zpět
  • Tento server

    Squeak
  • Úvod
  • Smalltalk
  • Články
  • Knihy
  • Dokumentace
  • FAQ
  • Tutoriály
  • Download
  • Odkazy

    Komunita
  • CSSUG
  • Oznámení
  • Projekty
  • O nás
  • Fórum
  • Kontakt

     

  • 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: aBlockvyhodnotí aBlok s každým elementem intervalu (self to: stop by: step) jako argumentem

    Vyhodnocovací řídící struktury (příjemce je Collection)

    do:aBlockpro každý prvek příjemce vyhodnoť aBlock s tímto prvkem jako argumentem

    Výběr (příjemce je Object)

    caseOf: aBlockAssociationCollectionOdpoví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: aBlockOdpoví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





    Administrátoři: Pavel Křivánek, Zbyněk Křivka