Lite modifierad Laboration 1 Körkortsprov för Smalltalk och VisualWorks Vissa anpassningar är gjorda för att passa VisualWorks- 3 991124, dock inte skärmdumpar (vilka är Visual- Works-2) /Björn 1 Inledning Avsikten med den här laborationen är att du ska få baskunskaper om: a) de olika delarna och filerna i Smalltalks omgivning, b) hur man startar, sparar och avslutar en Smalltalkomgivning (eng. Image), c) konstruerar, redigerar, hittar och sparar filer med hjälp av Smalltalks filredigerare och filhanterare (eng. file editor och file list), d) huvudmenyns (eng. Launcher) delar och grundläggande menyalternativ, e) ett arbetsfönster (eng. Workspace) för att i) göra enkel redigering av text och använda mus och menyer och ii) skriva in och utföra Smalltalkuttryck, f) uppbyggnaden av enklare Smalltalkuttryck, g) hur man använder kodkatalogen (eng. Browser) och h) hur klasser konstrueras och testas. 2 Innan du börjar Läs igenom kap. 1-3 i boken och de allmänna reglerna för laborationsredovisningarna. Se även punkt 15 nedan. 3 Starta Smalltalk 3.1 Konstruera en egen katalog För att förenkla administrationen av de filer som konstrueras under Smalltalklaborationerna bör du börja med att skapa en ny katalog avsedd för kursens laborationer. Gör t.ex. följande (i UNIX): mkdir MinSmalltalk Gå sedan ned i den nya katalogen med: cd MinSmalltalk Om du inte redan har gjort det: a) konstruera en egen Smalltalkkatalog och b) gå ned i denna katalog. 1
3.2 Var finns Smalltalk? På NADA:s UNIX-maskiner hittar du VisualWorks 3 i katalogen: /pkg/visual/3.0 3.3 Starta Smalltalk Du börjar en Smalltalksession genom att starta visrtuella maskinen med aktuell omgivningsfil (eng. image) som argument: DATAN>/pkg/visual/3.0/bin/visual /pkg/visual/3.0/image/visual.im I kommandot ovan har vi angett att den image som levereras med systemet ska användas. Om vi har en egen image anger vi denna som argument istället. Tex: DATAN>/pkg/visual/3.0/bin/visual minegenimage.im Om du har utfört module add visual/3.0 så hittar dock systemet visualworkskatalogen och det räcker att skriva: DATAN>visual minegenimage.im a) Starta nu Smalltalk med standardimagen! Smalltalksystemet startar nu och efter en stund ska följande fönster visas på skärmen: Figur 1 Omgivningen Det övre av dessa fönster är Smalltalks huvudmeny (Launcher), som också innehåller det så kallade Transcript-fönstret. Det undre fönstret är ett arbetsfönster (Workspace). 2 Lite modifierad Laboration 1
4 Filhanterare 4.1 Konstruera ny fil med filredigeraren Nu ska du skapa en fil i vilken du senare ska skriva in svaren på vissa av de frågor som ställs i laborationen. I Launchern finns en meny Tools. a) Aktivera denna meny genom att hålla ner musens vänstra knapp (selektionsknappen). b) Välj sedan menyalternativet File editor... genom att släppa musknappen ovanför detta alternativ c) Ge filen namnet svar.lab1 i den dialog (se figuren) som följer genom att skriva in detta namn i textfältet och klicka på knappen OK. Figur 2 Ge filnamnet i dialogen Därefter kommer du att behöva klicka på skärmen med vänster musknapp för att placera filredigerarens fönster d) Skriv någon ledtext samt gruppmedlemmarnas namn och e-postadresser i filredigerarens textfönster. e) Spara texten på fil m.h.a. musens mellersta knapp. Se figuren nedan. 7 Figur 3 Spara filredigerarens innehåll (med aktuellt namn) Lite modifierad Laboration 1 3
f) Skriv också in namnet på denna rubrik [d.v.s. 4.1 f)] följt av katalogen där du hittar Smalltalk på NADA:s UNIX-maskiner. 4.2 Användning av filhanteraren (eng. File List) (SER INTE RIKTIGT EXAKT UT SÅ HÄR IDAG! 991124) Under rubriken Tools i Launchern finns ett menyalternativ File List. Detta alternativ används så ofta att det finns en knapp för det på ikonraden under menyerna. 1. Skriv mönster och välj accept i mittknappsmenyn. 2. Då visas filer och kataloger som överensstämmer med 3. Här visas resultatet av urvalet. Textoperationer kan nu göras i detta Figur 4 Filhanterare a) Använd knappen för att öppna en File List. b) Använd denna filhanterare för att ta reda på alla filer eller kataloger i VisualWorks-2.5-katalogen och skriv in dem i din svarsfil. Skriv sökmönster i det övre delfönstret (* och # är jokertecken). Välj accept i mittknappsmenyn eller tryck RETURN på tangentbordet för att uppdatera det mellersta delfönstret. Välj önskad fil i det mellersta fönstrets listvy. Använd copy och paste. 4 Lite modifierad Laboration 1
c) Vad visas i det nedre delfönstret? 7 Figur 5 Spara innehåll på fil från File List Skriv in svaret i din fil direkt från File List-fönstret och spara. Se figuren ovan. 5 Ändra inställningar (ref till gamla dokumentationen 991124) Använd settingsdialogen, User s Guide kapitel 9, för att ändra följande (om det inte redan är gjort): a) Ange Use Enhanced Tools och Show UI for Globalization i UIOptions. Kan du med en mening säga vad detta inebär? Tips: help. b) Ändra skönsvärdet för text till Large font för Text i fönstren. Vilka fler alternativ finns det och vad innebär dom? c) Ange att du vill använda Document Printing och Postscript Printing när du skriver ut. Vad innebär alternativen? d) Vilka alternativ finns det för placering av nyskapade fönster (Window)? Lite modifierad Laboration 1 5
6 Spara, avsluta och återstarta omgivningen 6.1 Spara PROBLEM? Använd nu menyalternativet Save As... under rubriken File i Launchern för att spara din image i aktuell katalog. Använd skönsvärdet i den dialog som följer. Observera att det kan ta ett par minuter att spara, speciellt om nätet är belastat. a) Vilket namn fick den nya imagen? b) Vilka filer finns nu i din Smalltalkkatalog? Om du har otur är din disc quota för liten. Om så är fallet meddela någon handledare och hoppa över detta moment så länge. 6.2 Avsluta Använd menyalternativet Exit VisualWorks... i File-menyn för att avsluta sessionen! 6.3 Återstart Använd kommandot visual Smalltalk igen. a) Vad händer och hur ser imagen ut? 7 Arbetsfönstret (Workspace) 7.1 Öppna imagenamn i din Smalltalkkatalog för att starta a) Hur ser ikonen för Workspace ut i Launchern? b) Öppna ett Workspace genom att klicka på denna ikon. c) Vad skiljer mittknappsmenyn i ett Workspace från motsvarande meny i en File Editor respektive File List? d) Högerknappsmenyn i) Vilka är menyalternativen? ii) Pröva i tur och ordning vart och ett av dessa! 7.2 Exekvera kod Utför följande i ett Workspace: a) Skriv in texten Transcript show: Hello!, markera den (måla över) och använd menyalternativet do it i arbetsfönstrets mittknappsmeny. Vad händer? 6 Lite modifierad Laboration 1
b) Skriv nu också följande kod: 500 factorial. Vad händer om du markerar denna text och använder menyalternativet i) do it? ii) print it? c) Skriv nu in följande kod i fönstret: x x := 5. x * x / 10 Vad händer nu om vi markerar alla dessa tre rader och använder menyalternativet i) print it? ii) inspect? 8 Enkla Workspace-övningar 8.1 Enkel aritmetik i Smalltalk Skriv Smalltalksatser som korrekt beräknar följande matematiska uttryck. Utför dem med print it. Skriv både satser och resultat i din resultatfil. a) 3 + 4 b) c) 7 8 9 -- 3 4+ 5 d) e) f) 3 ( 4 + 5) 3 + 4 5 7 -- 9 6 Smalltalkutryck utförs från vänster till höger. Parenteser kan ändra ordningen! 9 Browsern Öppna en Browser genom att använda menyalternativet All Classes under rubriken Browse i Launchern. 9.1 Kategorier och klasser Leta reda på klassen Integer genom att använda kategorimenyn i System Browser. a) Använd menyalternativet find class... i kategorimenyn. Svara med en stjärna (*) följt av OK i dialogen som följer. b) Välj Integer i den efterföljande listvyn. c) Vad hände? Pröva mittknappssmenyn i delfönstret som visar klasser. Lite modifierad Laboration 1 7
d) Använd menyalternativet hierarchy i klasslistan, fortfarande med Integer som valt element. Vad visas i det undre delfönstret i Browsern? Figur 6 Mittknappsmenyn i klasslistan e) Beskriv vad som visas om du väljer menyalternativet comment. f) Beskriv vad som visas om du väljer menualternativet definition. 9.2 Klasshierarkier och kommentarer Använd den ovan beskrivna tekniken och besvara följande frågor a) Vilken klass är superklass till Object? nil i browsern betyder ingen superklass b) Vilka klasser är direkta subklasser till String, d.v.s. har String som närmaste superklass? 9.3 Kommentarer i metoder a) Vad står i kommentaren i metoden Object>>storeString? Använd menyalternativet find method... i den listvy i Browsern som visar meddelandekategorier. b) Vad står i kommentaren i metoden Object>>isNil? 9.4 Kategorin Magnitude-General a) Vilka är klasserna i kategorin Magnitude-General? b) Vilka är deras respektive superklasser? 8 Lite modifierad Laboration 1
10 Generella meddelanden; Object 10.1 Ett objekts klass a) I klassen Object finns en unär metod som ger det mottagande objektets klass. Vilken? Vilken meddelandekategori hör den till? Meddelandet har ett naturligt namn! b) Använd meddelandet från (a) för att ta reda på vilken klass den globala variabeln Smalltalk är instans av. 10.2 Reagerar ett objekt på ett visst meddelande? a) Vad säger kommentaren i metoden respondsto: i klassen Object? b) Använd meddelandet från (a) för att ta reda på om meddelandet between:and: kan skickas till heltalet 47. Vi skulle kunna använda detta för att ta reda på om följande kod är OK innan vi exekverar den: 47 between: 10 and: 35. Observera att respondsto: will ha en symbol som argument. Symbolen som representerar metodväljaren between:and: skrivs #between:and:. 11 Hitta i systemet med Launcher 11.1 Var implementeras en viss metod? a) Använd Launchern för att hitta alla metoder med namnet abs. i) Hur många är det? ii) I vilka klasser finns metoderna? Använd menyalternativet Implementators of... i Browse-menyn! b) Använd samma teknik som i (a) och ta reda på vilka metoder som börjar med while. Vilka är metoderna? Använd while* i dialogboxen Lite modifierad Laboration 1 9
11.2 Hitta de metoder som använder en viss metod a) Hitta alla metoder som skickar meddelandet iskindof:. Skriv inte in svaret i din svarsfil! Sök först reda på någon implementation av iskindof: och därefter: Figur 7 Vilka metoder skickar aktuellt meddelande? b) Används meddelandet av några metoder i klassen GraphicsContext? I så fall av vilka? Listan som ges som svar är sorterad i bokstavsordning med avseende på klassnamn. 12 Workspaceövningar med Collections Givet följande instans av Array vektorn := #(1 2 3 5-7 3 11 0 15 2 3 14-4) skriv Smalltalkuttryck som a) returnerar antalet element i vektorn, Använd meddelandet size. b) konstruerar en ny vektor där alla element har kvadrerats, collect: och squared. Exempel: #(1 2) collect: [:x x * 2] ger vektorn #(2 4). c) skapar en ny lista med alla element som är strikt positiva (> 0), select:, och klassen ArithmeticValue meddelandekategorin testing. Exempel: #(1 2) select: [:x x odd] ger vektorn #(1). d) skapar en ny lista med elementen sorterade i växande ordning (<=), assortedcollection. Exempel: #(1 2) assortedcollection #(1 2) assortedcollection: [:x :y x > y] 10 Lite modifierad Laboration 1
e) som tar reda på om 100 finns i vektorn eller inte, includes:. Exempel: #(1 2) includes: $x f) som säger oss hur många gånger 3 förekommer i vektorn. occurrencesof:. Exempel: #(1 2) occurencesof: $x 13 Konstruera en klass med Browser Nu ska du med hjälp av browsern konstruera en ny klass kallad Turtle. Som framgår av namnet är den tänkt att representera en sköldpadda. Vi tänker oss att en sköldpadda har en position och en riktning som representeras av instansvariabler. Förflyttning En sköldpadda kan antingen flyttas till en absolut position eller en viss sträcka i dess aktuella riktning. Riktningsförändring Riktningen ska gå att kontrollera genom att antingen ange en absolut vinkel eller en relativ vinkel (relativt sköldpaddans aktuella riktning). Följande figur illustrerar en situation med tre instanser av Turtle. 0@0 100 x 270 100@40 b 225 100 y a 35@80 90 c 180@70 Figur 8 Koordinatsystem och paddor Figuren visar också att Smalltalks koordinatsystem har origo högst upp till vänster och följaktligen blir den positiva rotationsvinkeln medurs. Nollriktningen är (som vanligt) längs abskissan (x-axeln). I figuren är också sköldpaddornas positioner och rotationsvinklar inskrivna. Som framgår skrivs punkter (instanser av Point) på formen x-koordinat@y-koordinat. 13.1 Konstruera ny kategori Konstruera en ny klasskategori genom att i browserns kategorimeny använda menyalternativet add... och sedan i efterföljande dialogbox ange önskat namn, t.ex. OOPK-Lab1. Lite modifierad Laboration 1 11
13.2 Definition Konstruera sedan en klass med följande klasshuvud: Object subclass: #Turtle instancevariablenames: position direction classvariablenames: pooldictionaries: category: OOPK-Lab1 13.3 Ny meddelandekategori Skriv in texten m.h.a. browsern, markera texten och använd menyalternativet accept. Skapa en ny meddelandekategori med namnet accessing. 13.4 Metoder för att läsa instansvariabler Skriv metoder för att läsa instansvariablerna. Ge inspektorerna följande namn: position Returnera sköldpaddans position. direction Returnera sköldpaddans riktning. Se till att metoderna hamnar i kategorin accessing. 13.5 Metoder för att ändra instansvariabler Skriv följande instansmetoder avsedda att tilldela det givna argumentets värde till respektive instansvariabel: position: apoint Ändra sköldpaddans position, där apoint är instans av klassen Point. direction: anangle Ändra sköldpaddans riktning, där vinkeln anges i grader. 12 Lite modifierad Laboration 1
13.6 Testkörning av koden I ETT WORKSPACE Nu kan vi pröva det vi har skrivit hittills genom att t.ex. konstruera instanser av Turtle i ett Workspace och på vanligt sätt markera och använda print it eller do it från mittknappsmenyn. I figuren nedan illustreras detta. Först använder vi menyalternativet print it och får resultatet utskrivet i fönstret do it här ger utmatning i Transcript, i det här fallet nil två gånger. Varför nil? Här matar vi också ut i Transcript men har satt position och riktning för MED INSPECTFÖNSTER Figur 9 Test av kod i ett Workspace där bl.a. Transcript används som utmatningsfönster. En trevligare och bättre teknik är att använda Inspect-fönster. Alla objekt förstår meddelandet inspect. Om vi skickar detta till ett objekt så öppnas ett speciellt fönster för att inspektera den aktuella instansen. Istället för att explicit skicka Lite modifierad Laboration 1 13
meddelandet inspect kan man markera det som ska inspekteras och välja inspect i mittknappsmenyn i ett Workspace. Båda sätten medför att ett Inspect-fönster öppnas Figur 10 Inspektion av ett objekt Man kan se variablernas värden genom att klicka på dem och även ändra dem genom att skriva in nytt värde följt av accept i menyn. Figur 11 Inspektion och ändring av attributet position. 14 Lite modifierad Laboration 1
Det går precis som i ett Workspace att skicka meddelanden till objekt i ett Inspectfönster. Pseudovariabeln self representerar då den inspekterade instansen. 13.7 Fler instansmetoder Figur 12 Evaluering av kod i Inspect-fönster. Nu ska du utöka klassen Turtle med några ytterligare instansmetoder. Du får själv välja lämpliga namn på de meddelandekategorier/protokoll som du placerar metoderna i. RELATIV FLYTTNING AV SKÖLDPADDA Skriva en metod som flyttar sköldpaddan en viss sträcka längs med dess aktuella riktning. Skriv metoden i form av en nyckelordsmetod med en formell parameter, go: distance, där distance ska vara ett tal som anger hur långt sköldpaddan ska flyttas. Lite modifierad Laboration 1 15
Metodförslag (pseudokod i kursiv stil): go: distance dir := aktuell-riktning-i-radianer scalefactor := dir cos @ dir sin. self position:scalefactor multiplicerad med distance + aktuell position RELATIV RIKTNINGSFÖRÄNDRING Det finns en metod degreestoradians. Skriv också en metod turn: angle, för att rotera (d.v.s. uppdatera direction för) en sköldpadda med ett givet antal grader relativt aktuell rikning. Om vi t.ex. gör a turn: 45 i Figur 8 ovan får vi följande situation: 0@0 100 x b 100 y a 315 100@40 225 35@80 90 c 180@70 AVSTÅND MELLAN SKÖLDPADDOR Figur 13 Padda a roterad 45 grader Skriv en metod dist: anotherturtle, som ger det vinkelräta avståndet mellan sköldpaddan som är mottagare av meddelandet och den som ges som argument. En sköldpaddas position är instans av klassen Point. I meddelandekategorin point functions i klassen Point finns en lämplig metod som returnerar avståndet mellan mottagare och en punkt som ges som argument! Exempel: Om vi t.ex. vill skapa paddorna a och b enligt Figur 13 ovan (men utan rotationer) och sedan mäta avståndet mellan dem kan vi göra det med följande enkla kodavsnitt: a b a := Turtle new. b := Turtle new. a position: 35@80. b position: 100@40. a dist: b Detta ska ge svaret 76.3217. 13.8 Ändring av metod och definition ÄNDRA EN METOD Ändra metoden direction: anangle, så att instansvariabeln direction alltid tillhör det halvöppna intervallet [0, 360). meddelandet \\ ger mottagaren modulo argumentet. Exempel: 70 \\ 9 ger svaret 7. 16 Lite modifierad Laboration 1
ÄNDRA DEFINITION För att bl.a. enklare kunna identifiera en viss sköldpadda, lägg till en instansvariabel name i klassdefinitionen. Skriv också lämpliga metoder för att läsa respektive uppdatera denna variabel. 13.9 Initieringsmetoder Vi kan fortfarande konstruera instanser av Turtle som inte har initialiserat sina instansvariabler på lämpligt sätt. Detta kan i värsta fall medföra att exekvering av vissa metoder misslyckas. T.ex. fås ett felavbrott om meddelandet dist: skickas till en oinitialiserad padda. Nu ska vi åtgärda detta och också skriva ett par klassmetoder som gör instansieringen enklare. INSTANSMETODER FÖR INITIERING Skriv en metod initialize som på lämpligt sätt ger skönsvärden för instansvariablerna direction och position då den anropas. Vidare ska en pekare till mottagande objekt alltid returneras som resultat från metoden. Fast det senare är ju trivialt! Varför? a) Skriv din kod i svarsfilen. b) Vad returneras från metoden om vi inte explicit returnerar någonting från den, d.v.s om vi inte skriver ^ följt av ett uttryck i koden? Beskriv med högst tio ord! NY KONSTRUKTÖR Exempel: turtle turtle := Turtle new. turtle initialize ska ge en lämpligt initierad padda. Man kan också skriva turtle turtle := Turtle new initialize. c) Lösningen ovan är fortfarande inte riktigt tillfredställande då vi i alla fall kan glömma att anropa initialize och därmed lämna objektet oinitialiserat. Därför ska du nu skriva om klassmetoden (konstruktören) new så att den automatiskt anropar initialize för det nya objektet. Skapa en klassmeddelandekategori instance creation och placera metoden: där new ^super new initialize Klassmetoder visas och kan redigeras då knappen class är nertryckt i Browsern. (Du kan då inte se instansmetoderna.) Pröva! super new skapar en ny Turtle m.h.a. den new-metod som Turtle har ärvt ifrån basklassen Object. Lite modifierad Laboration 1 17
d) Vad skulle ha hänt om du istället hade skrivit: new ^self new initialize. "Detta är felaktigt. Varför?" FLER KLASSMETODER Nu ska vi skriva ytterligare två klassmetoder som gör det lite smidigare att direkt konstruera instanser av Turtle med given position eller riktning. Skriv först: position: initialposition direction: initialangle instance instance := self new. instance position: initialposition. instance direction: initialangle. ^instance e) Hur kan vi skriva om denna metod utan att använda den (här onödiga) initialiseringen som görs via klassmeddelandet new? se c)-uppgiften. Skriv också följande klassmetod: position: initialposition ^self position: initialposition direction: Number zero f) Pröva samt beskriv vilka meddelanden som sänds då vi utför följande kod: 14 Spara på fil Turtle position: 234@60 Som avslutning ska du skriva ut din klasskategori på en fil som vanlig text! a) Hur gör man det? b) Om du senare vill läsa in denna kod i en image hur gör du då? 15 Redovisa Redovisningen består dels i att visa upp en papperskopia på filen med svaren på de frågor som ställts i labben, dels i att klassen Turtle provkörs och koden tittas igenom. Var noga med att koden uppfyller de allmänna krav som gäller för labbarna. 18 Lite modifierad Laboration 1