Changes between Version 11 and Version 12 of squeak_faq
- Timestamp:
- 10/14/2013 03:59:48 PM (11 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
squeak_faq
v11 v12 10 10 === Wo finde ich Dokumentation? === 11 11 12 Es gibt für einige Klassen Dokumentation gleich im Browser. Der ?Button zwischen Class und Instance zeigt die Klassenkommentare an.12 Es gibt für einige Klassen Dokumentation gleich im Browser. Der "?" Button zwischen Class und Instance zeigt die Klassenkommentare an. 13 13 Weiterhin findet ihr hier Informationen: 14 14 … … 16 16 * [http://squeakbyexample.org/ Squeak by Example] 17 17 18 * [http://static.squeak.org/tutorials/morphic-tutorial-1.html Morphic Tutorial 19 20 * [http://wiki.squeak.org/squeak/30 Squeak-Wiki 18 * [http://static.squeak.org/tutorials/morphic-tutorial-1.html Morphic Tutorial] 19 20 * [http://wiki.squeak.org/squeak/30 Squeak-Wiki] 21 21 22 22 … … 33 33 34 34 Zum Einstieg in !Squeak/Smalltalk sind viele gute Bücher kostenlos 35 verfügbar. Eine gute Übersicht bietet: 36 [href="http://stephane.ducasse.free.fr/FreeBooks.html Free Books] 35 verfügbar. Eine gute Übersicht bietet [http://stephane.ducasse.free.fr/FreeBooks.html Stephane Ducasse: Free Books] 37 36 38 37 … … 41 40 === Wie werden Grafiken im Image verwendet? === 42 41 43 Der Dreh und Angelpunkt ist hier die Klasse Form. Die Basis von Form ist die "Squeak Canvas", eine Bitmap, die Bilder enthält, oder auf der gezeichnet werden kann. Diese Objekte können dann in !ImageMorphs verwendet werden. Bei größeren oder vielen Bildern lohnt ein Blick auf die Klassenseite von Form. Da gibt es eine Methode, die aus einer Datei direkt ein Form-Objekt lädt. Ähnliches findet sich auch auf den Klassenseiten von den Klassen PNGReadWriter, JPEGReadWriter, GIFReadWriter und weitere für spezielle Bildformate. Mit Klassen wie !FileDirectory oder !FileUrl kann im Dateisystem navigiert werden. Hierbei gilt es auch zu bedenken, dass die "Pathdelimiter" der Betriebssysteme unterschiedlich sein können (/ oder \). Bilder können auch im Image gespeichert werden. Das hat den Vorteil, das ihr die Bilder über Monticello verwalten könnt und so alle Teammitglieder über das Repository die aktuellen Bilder bekommen. Der große Nachteil ist, dass ihr die Größe des Images aufbläht. Wenn trotz ihr trotz dieses Nachteils Bilder in Methoden und damit im Image speichern wollt, könnt ihr Array-Repräsentationen gewinnen. Dazu laded ihr das Bild, wie oben beschrieben, zuerst in eine Form und aus dieser erzeugt ihr dann das Array (siehe. z.B. ` `Form>>storeOn``). Es gibt in Squeak den !ImageReadWriter als abstrakte Klasse und dazu verschiedene Implementierungen für z.B. BMP und PNG (PNGReadWriter, BMPReadWriter). Auf Klassenseite von !ImageReadWriter findet sich dann auch ``ImageWriter ``class>>formFromFileNamed``:``, was in der konkreten Implementierung genutzt werden kann.42 Der Dreh und Angelpunkt ist hier die Klasse Form. Die Basis von Form ist die "Squeak Canvas", eine Bitmap, die Bilder enthält, oder auf der gezeichnet werden kann. Diese Objekte können dann in !ImageMorphs verwendet werden. Bei größeren oder vielen Bildern lohnt ein Blick auf die Klassenseite von Form. Da gibt es eine Methode, die aus einer Datei direkt ein Form-Objekt lädt. Ähnliches findet sich auch auf den Klassenseiten von den Klassen PNGReadWriter, JPEGReadWriter, GIFReadWriter und weitere für spezielle Bildformate. Mit Klassen wie !FileDirectory oder !FileUrl kann im Dateisystem navigiert werden. Hierbei gilt es auch zu bedenken, dass die "Pathdelimiter" der Betriebssysteme unterschiedlich sein können (/ oder \). Bilder können auch im Image gespeichert werden. Das hat den Vorteil, das ihr die Bilder über Monticello verwalten könnt und so alle Teammitglieder über das Repository die aktuellen Bilder bekommen. Der große Nachteil ist, dass ihr die Größe des Images aufbläht. Wenn trotz ihr trotz dieses Nachteils Bilder in Methoden und damit im Image speichern wollt, könnt ihr Array-Repräsentationen gewinnen. Dazu laded ihr das Bild, wie oben beschrieben, zuerst in eine Form und aus dieser erzeugt ihr dann das Array (siehe. z.B. `Form>>storeOn`). Es gibt in Squeak den !ImageReadWriter als abstrakte Klasse und dazu verschiedene Implementierungen für z.B. BMP und PNG (PNGReadWriter, BMPReadWriter). Auf Klassenseite von !ImageReadWriter findet sich dann auch `ImageWriter `class>>formFromFileNamed`:`, was in der konkreten Implementierung genutzt werden kann. 44 43 45 44 … … 55 54 === Wie schaffe ich es, dass ein Morph nicht mehr verschiebbar ist? === 56 55 57 Werft einen Blick auf die Methode ` `Morph>>lock``.56 Werft einen Blick auf die Methode `Morph>>lock`. 58 57 59 58 … … 104 103 === Wir wollen einen Morph (inklusive Submorphs) als .png Datei abspeichern. === 105 104 106 Verwendet dazu ` `Morph>>exportAsPng``.105 Verwendet dazu `Morph>>exportAsPng`. 107 106 108 107 … … 118 117 === Gibt es in Squeak eine Möglichkeite Bilder in eine Package einzubetten als Ressource? Oder kann man Bilder nur aus Dateien laden? === 119 118 120 Die Klasse !SystemWindow besitzt eine Reihe von Class-methods, die allesamt auf *Image enden. (z.B. ` `SystemWindow>>menuBoxImage``)119 Die Klasse !SystemWindow besitzt eine Reihe von Class-methods, die allesamt auf *Image enden. (z.B. `SystemWindow>>menuBoxImage`) 121 120 Diese Methoden geben Arrays zurück, die die Bildinformationen enthalten aus denen dann Form-Objekte erzeugt werden. 122 121 Form ist die "Squeak's Canvas". Eine Bitmap, die Bilder enthalten kann oder auf der gezeichnet … … 131 130 Mit Klassen wie !FileDirectory oder !FileUrl kann im Dateisystem navigiert werden. 132 131 Hierbei gilt es auch zu bedenken, dass die "Pathdelimiter" der Betriebssysteme unterschiedlich 133 sein können (/ oder \, ). Für Plattformunabnhängigkeit könnt ihr ` `GRPlatform>>pathSeparator``.132 sein können (/ oder \, ). Für Plattformunabnhängigkeit könnt ihr `GRPlatform>>pathSeparator`. 134 133 135 134 … … 137 136 und damit im Image gespeichert werden sollen, können Array-Repräsentationen 138 137 gewonnen werden, indem das Bild, wie oben beschrieben, in eine Form geladen wird 139 und aus dieser dann das Array (s. z.B. ` `Form>>storeOn``).138 und aus dieser dann das Array (s. z.B. `Form>>storeOn`). 140 139 141 140 … … 159 158 160 159 Anzumerken ist, dass der von Textmorphs enthaltene Text direkt auf diesem verändert werden kann. 161 Dabei ist die Eingabe in !TextMorphs durchaus gewollt. Wenn ihr dies verhindern wollt, müsst ihr sie locken. Weiterhin brechen diese Morphs automatisch den Text um, wenn der Platz (definiert durch die Bounds) nicht ausreichend ist. Das so genannte Word Wrapping kann aber auch deaktiviert werden (siehe ` `TextMorph>>wrapOnOff``). Wenn in einer Zeile mehr als nur 3-4 Zeichen geschrieben werden sollen, so muss man ihm eben mehr Platz geben also vergrößern. Beide Eigenschaften lassen sich auch mit dem vorgefertigten !TextMorph über Halos und Menüs implementieren.160 Dabei ist die Eingabe in !TextMorphs durchaus gewollt. Wenn ihr dies verhindern wollt, müsst ihr sie locken. Weiterhin brechen diese Morphs automatisch den Text um, wenn der Platz (definiert durch die Bounds) nicht ausreichend ist. Das so genannte Word Wrapping kann aber auch deaktiviert werden (siehe `TextMorph>>wrapOnOff`). Wenn in einer Zeile mehr als nur 3-4 Zeichen geschrieben werden sollen, so muss man ihm eben mehr Platz geben also vergrößern. Beide Eigenschaften lassen sich auch mit dem vorgefertigten !TextMorph über Halos und Menüs implementieren. 162 161 163 162 … … 218 217 semaphore wait. 219 218 }}} 220 Für einfache Nebenläufigkeit ohne Synchronisation existiert ` `BlockClosure>>fork``.219 Für einfache Nebenläufigkeit ohne Synchronisation existiert `BlockClosure>>fork`. 221 220 {{{ 222 221 [50000 factorial] forkAt: ProcessScheduler userBackgroundPriority … … 225 224 226 225 227 === Was ist die richtige Art, Klassenvariablen anzulegen? Auf Instanzseite in ` `classVariableNames:`` oder auf Klassenseite in ``instanceVariableNames:``? ===226 === Was ist die richtige Art, Klassenvariablen anzulegen? Auf Instanzseite in `classVariableNames:` oder auf Klassenseite in `instanceVariableNames:`? === 228 227 229 228 Dafür ist die instanzseitige Klassenvariable die richtige Wahl. Die klassenseitige Instanzvariable existiert nur auf Grund der Tatsache, dass Squeak ein Metaobjectprotocol besitzt und somit Klassen selbst wieder Instanz einer anderen Klasse sind. Daher besitzen sie auch Instanzvariablen. Allerdings sind die Instanzvariablen auch nur für die Klasse und nicht für Ihre Instanzen einsehbar. … … 245 244 === Hilfe, ich habe hunderte Morphs die alle eine falsche Methode steppen. Was kann ich sie stoppen? === 246 245 247 1.) Wenn es sich um eine einzige Methode handelt, könntest du versuchen diese mit einem "User Interrupt" zu unterbrechen: strg /alt und . (!Windows/Linux) bzw. cmd und . (Mac)246 1.) Wenn es sich um eine einzige Methode handelt, könntest du versuchen diese mit einem "User Interrupt" zu unterbrechen: strg + . (Windows) alt + . (Linux), cmd + . (OS X) 248 247 249 248 … … 504 503 Das kommt sehr auf eure Netzwerkimplementierung an. Nutz ihr ein Standardprotokoll, so sollte die verwendete Bibliothek im Allgemeinen auch entsprechende Methoden bereitstellen. Häufig sind diese transparent, so dass die Methoden automatisch gerufen werden, sobald ein neuer Request eintrifft. Um Beispiele dafür zu sehen, schaut euch einmal im Image den WAListener an, welcher den Webserver für Seaside implementiert. Dort wird auch gezeigt wie man Prozesse "forked" um mehrere Requests gleichzeitig zu behandeln. 505 504 506 Von dem Ansatz die ganze Sache in Morphic und dessen #step Methode abzubilden, raten wir schlichtweg ab. Der Grund: die #step Methode ist nur scheinbar parallelisiert und sollte eine Methode auf ` `SocketStream>>isDataAvailable`` warten, steht das ganze System. Ihr müsste also auf jeden Fall mit mehreren Prozessen arbeiten. Dafür verwendet ihr wie gesagt die ``fork``-methode.505 Von dem Ansatz die ganze Sache in Morphic und dessen #step Methode abzubilden, raten wir schlichtweg ab. Der Grund: die #step Methode ist nur scheinbar parallelisiert und sollte eine Methode auf `SocketStream>>isDataAvailable` warten, steht das ganze System. Ihr müsste also auf jeden Fall mit mehreren Prozessen arbeiten. Dafür verwendet ihr wie gesagt die `fork`-methode. 507 506 508 507 Um das Warten zu realisieren, schaut euch die Klasse Delay an. 509 508 Es gibt aber noch weiter Synchronisationsprimitiven, insbesondere wenn ihr Sockets benutzt: 510 Je nachdem ob ihr Socket oder !SocketStream verwendet, gibt es entsprechende Methoden die sich schlafen legen bis Daten verfügbar sind, z.B. ` `Socket>>waitForData`` (siehe Kommentar).509 Je nachdem ob ihr Socket oder !SocketStream verwendet, gibt es entsprechende Methoden die sich schlafen legen bis Daten verfügbar sind, z.B. `Socket>>waitForData` (siehe Kommentar). 511 510 512 511 Die Netzwerkfähigkeit wäre zwar sicher ein schönes Feature ist aber ohne entsprechende Vorkenntnisse in dem Bereich nicht ganz einfach. Überlegt es euch daher vielleicht, ob ihr dies wirklich implementieren möchtet. … … 526 525 Dort habt ihr eine MD5 Klasse. Folgt dem Beispiel in der Methode 527 526 #hashStream:. Aber Achtung, [http://de.wikipedia.org/wiki/MD5 MD5] ist sehr unsicher, da sehr leicht Kollisionen gefunden werden können. 528 Seaside nutzt deswegen üblicherweise den SHA Algorithmus. Diesen könnt ihr bereits in eurem Image finden unter der Klasse ` `SecureHashAlgorithm`. Dort schaut euch einfach die Methoden unter dem 'public' Protokoll an.527 Seaside nutzt deswegen üblicherweise den SHA Algorithmus. Diesen könnt ihr bereits in eurem Image finden unter der Klasse `SecureHashAlgorithm`. Dort schaut euch einfach die Methoden unter dem 'public' Protokoll an. 529 528 530 529 … … 540 539 'abc' , Character tab , 'abc' 541 540 }}} 542 da ` `String>>``,`` die Nachricht #asString an seinen Parameter sendet. Unterschiedlich sieht das nur aus wenn man es per print it (cmd/strg + p) ausgibt, da tab halt je nach Position in unterschiedlicher Länge gerendert wird. Die Strings sind aber gleich (im Sinne von #=).541 da `String>>`,` die Nachricht #asString an seinen Parameter sendet. Unterschiedlich sieht das nur aus wenn man es per print it (cmd/strg + p) ausgibt, da tab halt je nach Position in unterschiedlicher Länge gerendert wird. Die Strings sind aber gleich (im Sinne von #=). 543 542 544 543 Bedenkt bitte, dass ihr bei sehr komplexen String Konkatenationen besser auf Streams zurückgreifen solltet: