<body><div id="__MailbirdStyleContent" style="font-size: 12pt;font-family: calibri;color: #000000">
                                        The dynamically-scoped "ActiveWorld", which is technically not quite comparable with the global "World", is in line with ActiveEvent and ActiveHand. One would have to remove all three concepts.<div><br></div><div>"World", instead, is a duplicate of "Project current world".</div><div><br></div><div>Since we have to alternative for "ActiveWorld" at the moment, we cannot change it.</div><div><br></div><div>Best,</div><div>Marcel</div><div class="mb_sig"></div><blockquote class="history_container" type="cite" style="border-left-style:solid;border-width:1px; margin-top:20px; margin-left:0px;padding-left:10px;">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 14.11.2017 18:31:10 schrieb Chris Muller <asqueaker@gmail.com>:</p>Shouldn't we be getting rid of ActiveWorld first then, instead of "World"?<br><br>Globals are fine when they're part of a set of "roots" or basic<br>objects to access to the system.  For example, "Smalltalk", or<br>"Transcript" or "Processor" or "World".<br><br>It's when we have globals that participate in "logic" (i.e., in this<br>case, "active" vs. inactive) which is the kind of bad-design global<br>that hurts the quality of the system.<br><br> - Chris<br><br>On Tue, Nov 14, 2017 at 2:25 AM, Marcel Taeumel <marcel.taeumel@hpi.de> wrote:<br>> Hmm...  in our current use of Morphic, there is no difference between<br>> "World" and "ActiveWorld". Back then, "World" was the outermost world and<br>> "ActiveWorld" was the world that is involved in the particular event<br>> dispatch (see ActiveEvent, too), which could be in a window, for example.<br>> For everyday debugging, one should use "ActiveWorld" instead of "World". If<br>> we manage to get "worlds in worlds" working again (see Squeak 2.0 for<br>> example), "World" would not return the correct object anymore. It might be<br>> confusing.<br>><br>> Anyway, there is no need to completely remove World as such. Just remove all<br>> senders to it in application code. :)<br>><br>> Best,<br>> Marcel<br>><br>> Am 14.11.2017 05:25:57 schrieb H. Hirzel <hannes.hirzel@gmail.com>:<br>><br>> On 11/14/17, David T. Lewis wrote:<br>>> I had wondered the same thing, but I have not raised the question. I<br>>> expect<br>>> that the right thing to do would be to remove all references to the global<br>>> in the code, but to retain the actual global. After all, its value is only<br>>> set in a couple of methods, so that is easy enough to maintain.<br>><br>> Yes.<br>><br>>> Aside from the point you are raising, I would also be concerned that<br>>> there are externally maintained packages that may expect these well-known<br>>> global variables to be present. Etoys would be an obvious example, but<br>>> there probably are others.<br>><br>> Indeed. Unnecessary references to the globals World and ActiveWorld<br>> should be reduced but they should be maintained.<br>><br>><br>> It still would be good to now what the difference between World and<br>> ActiveWorld is.....<br>><br>> Open question here:<br>><br>> ActiveWorld<br>> http://wiki.squeak.org/squeak/1104<br>><br>><br>>> Yes I know tha Etoys is in the trunk right now,<br>>> but hopefully it will be a fully reloadable package that can be maintained<br>>> independently, and I would expect that Scratch and various other<br>>> externally<br>>> maintained things might have expectations regarding well-known globals.<br>>><br>>> From my personal perspective, success means that if I were to remove the<br>>> global variable World, the system would still work. Sort of like having<br>>> MVC be reloadable: I want to be able to unload it, load it back into the<br>>> system, and have MVC still be working. Once that is done, I am happy.<br>>> That does not mean I would actually remove MVC from any image that I<br>>> actually use, why would anyone ever want to do that?!?<br>>><br>>> Dave<br>>><br>>><br>>> On Mon, Nov 13, 2017 at 09:51:41PM -0600, Chris Muller wrote:<br>>>> Thanks for the clarification, however I'm still not clear if you're<br>>>> saying you intend to remove "World" as a Smalltalk global, or only<br>>>> references to it in the code. I hope only the latter. It starts to<br>>>> become cumbersomely wordy is in everyday debugging having to type<br>>>> "Project current world submorphs detect: [ ... ]" in inspectors to<br>>>> find my morph instead of only "World submorphs detect: [ ...]".<br>>>><br>>>> - Chris<br>>>><br>>>> On Mon, Nov 13, 2017 at 9:23 PM, David T. Lewis<br>>>> wrote:<br>>>> > Hi Chris,<br>>>> ><br>>>> > I did not intend to move all those packages to trunk right after you<br>>>> > posted this, I had thought that there were no further comments and did<br>>>> > not see your message while I was doing the moves. The neglect was not<br>>>> > intentional.<br>>>> ><br>>>> > On Mon, Nov 13, 2017 at 07:29:29PM -0600, Chris Muller wrote:<br>>>> >> Why? This is a sad move for users who want to program the<br>>>> >> environment, and it does little or nothing to make it any safer. Is<br>>>> >> it because "globals are bad?" I hope not.<br>>>> >><br>>>> >> Should I assume that you mean to make Display, Processor, and other<br>>>> >> globals disappear too? If so, what about classes, as Smalltalkers we<br>>>> >> like to tell people they're "objects" too, so why make this sort of<br>>>> >> access "exceptional" to classes only?<br>>>> ><br>>>> > No, it is quite specific to the problem of project navigation, as well<br>>>> > as better support of multiple (possibly concurrent?) project types. The<br>>>> > idea is to avoid using globals to cache information that is, or should<br>>>> > be,<br>>>> > local to a Project. I have spent some time debugging these things in<br>>>> > the<br>>>> > past, and is quite clear to me that unnecessary use of globals for<br>>>> > things<br>>>> > that are not really global is a Really Bad Idea, especially when you<br>>>> > are<br>>>> > dealing with things that drop you into an emergency evaluator when they<br>>>> > do not work.<br>>>> ><br>>>> > To some extent I am also looking forward to Morphic3 which is being<br>>>> > developed<br>>>> > in Cuis. It should in principle be able to host this in Squeak, and I<br>>>> > did<br>>>> > some work a number of years ago<br>>>> > (http://www.squeaksource.com/SimpleMorphicSqueak)<br>>>> > on an early proof of concept. That proof of concept was "successful" in<br>>>> > the sense that it worked, but it was also quite clear that some<br>>>> > housekeeping<br>>>> > was was going to be needed in Squeak (specifically around Projects) in<br>>>> > order<br>>>> > for things like this to be sustainable beyond just the proof of concept<br>>>> > level. So I am not trying to take anything away from Squeak, just<br>>>> > trying<br>>>> > to scratch a long standing itch and maybe tidy up the system a little<br>>>> > bit<br>>>> > in the process.<br>>>> ><br>>>> > I hope you understand that "world global elimination" was just a small<br>>>> > joke, I do not really intend to make any important things disappear ;-)<br>>>> ><br>>>> > Dave<br>>>> ><br>>>> >><br>>>> >> On Sat, Nov 11, 2017 at 3:05 PM, wrote:<br>>>> >> > David T. Lewis uploaded a new version of MorphicExtras to project<br>>>> >> > The<br>>>> >> > Inbox:<br>>>> >> > http://source.squeak.org/inbox/MorphicExtras-dtl.214.mcz<br>>>> >> ><br>>>> >> > ==================== Summary ====================<br>>>> >> ><br>>>> >> > Name: MorphicExtras-dtl.214<br>>>> >> > Author: dtl<br>>>> >> > Time: 11 November 2017, 4:05:52.716283 pm<br>>>> >> > UUID: 297c9f00-e80a-4a90-a1aa-5f3a26a835d0<br>>>> >> > Ancestors: MorphicExtras-pre.213<br>>>> >> ><br>>>> >> > World global elimination. Once the current project has been entered,<br>>>> >> > Project current world == World. Begin eliminating references to the<br>>>> >> > global variable World in cases where it is not required.<br>>>> >> ><br>>>> >> > =============== Diff against MorphicExtras-pre.213 ===============<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: BookMorph>>loadImagesIntoBook (in category 'menu')<br>>>> >> > -----<br>>>> >> > loadImagesIntoBook<br>>>> >> > "PowerPoint stores GIF presentations as individual slides<br>>>> >> > named Slide1, Slide2, etc.<br>>>> >> > Load these into the book. mjg 9/99"<br>>>> >> ><br>>>> >> > | directory filenumber form newpage |<br>>>> >> > directory := ((StandardFileMenu oldFileFrom: FileDirectory<br>>>> >> > default)<br>>>> >> > ifNil: [^nil]) directory.<br>>>> >> > directory isNil ifTrue: [^nil].<br>>>> >> ><br>>>> >> > "Start loading 'em up!!"<br>>>> >> > filenumber := 1.<br>>>> >> > [directory fileExists: 'Slide' , filenumber asString]<br>>>> >> > whileTrue:<br>>>> >> > [Transcript<br>>>> >> > show: 'Slide' , filenumber asString;<br>>>> >> > cr.<br>>>> >> > Smalltalk bytesLeft <><br>>>> >> > ifTrue:<br>>>> >> > ["Make some room"<br>>>> >> ><br>>>> >> > (self valueOfProperty: #url)<br>>>> >> > isNil<br>>>> >> > ifTrue: [self<br>>>> >> > savePagesOnURL]<br>>>> >> > ifFalse: [self<br>>>> >> > saveAsNumberedURLs]].<br>>>> >> > form := Form<br>>>> >> > fromFileNamed:<br>>>> >> > (directory fullNameFor: 'Slide' , filenumber asString).<br>>>> >> > newpage := PasteUpMorph new extent: form<br>>>> >> > extent.<br>>>> >> > + newpage addMorph: (Project current world<br>>>> >> > drawingClass withForm: form).<br>>>> >> > - newpage addMorph: (World drawingClass<br>>>> >> > withForm: form).<br>>>> >> > self pages addLast: newpage.<br>>>> >> > filenumber := filenumber + 1].<br>>>> >> ><br>>>> >> > "After adding all, delete the first page."<br>>>> >> > self goToPage: 1.<br>>>> >> > self deletePageBasic.<br>>>> >> ><br>>>> >> > "Save the book"<br>>>> >> > (self valueOfProperty: #url) isNil<br>>>> >> > ifTrue: [self savePagesOnURL]<br>>>> >> > ifFalse: [self saveAsNumberedURLs]!<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: GraphicalDictionaryMenu>>handMeOne (in category 'menu<br>>>> >> > commands') -----<br>>>> >> > handMeOne<br>>>> >> > + self currentHand attachMorph: (Project current world<br>>>> >> > drawingClass new form: (formChoices at: currentIndex))!<br>>>> >> > - self currentHand attachMorph: (World drawingClass new form:<br>>>> >> > (formChoices at: currentIndex))!<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: GraphicalDictionaryMenu>>repaintEntry (in category<br>>>> >> > 'menu commands') -----<br>>>> >> > repaintEntry<br>>>> >> > "Let the user enter into painting mode to repaint the item<br>>>> >> > and save it back."<br>>>> >> ><br>>>> >> > | aWorld bnds sketchEditor aPaintBox formToEdit |<br>>>> >> ><br>>>> >> > (aWorld := self world) assureNotPaintingElse: [^ self].<br>>>> >> ><br>>>> >> > aWorld prepareToPaint.<br>>>> >> > aWorld displayWorld.<br>>>> >> > formToEdit := formChoices at: currentIndex.<br>>>> >> > bnds := (submorphs second boundsInWorld origin extent:<br>>>> >> > formToEdit extent) intersect: aWorld bounds.<br>>>> >> > bnds := (aWorld paintingBoundsAround: bnds center) merge:<br>>>> >> > bnds.<br>>>> >> > sketchEditor := SketchEditorMorph new.<br>>>> >> > aWorld addMorphFront: sketchEditor.<br>>>> >> > + sketchEditor initializeFor: ((aWorld drawingClass withForm:<br>>>> >> > formToEdit) position: submorphs second positionInWorld) inBounds:<br>>>> >> > bnds pasteUpMorph: aWorld paintBoxPosition: bnds topRight.<br>>>> >> > - sketchEditor initializeFor: ((World drawingClass withForm:<br>>>> >> > formToEdit) position: submorphs second positionInWorld) inBounds:<br>>>> >> > bnds pasteUpMorph: aWorld paintBoxPosition: bnds topRight.<br>>>> >> > sketchEditor<br>>>> >> > afterNewPicDo: [:aForm :aRect |<br>>>> >> > formChoices at: currentIndex put: aForm.<br>>>> >> > baseDictionary at: (entryNames at:<br>>>> >> > currentIndex) put: aForm.<br>>>> >> > self updateThumbnail.<br>>>> >> > (aPaintBox := aWorld paintBoxOrNil) ifNotNil:<br>>>> >> > [aPaintBox delete]]<br>>>> >> > ifNoBits:<br>>>> >> > [(aPaintBox := aWorld paintBoxOrNil)<br>>>> >> > ifNotNil: [aPaintBox delete]].<br>>>> >> ><br>>>> >> > !<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: ProjectSorterMorph>>addControls (in category<br>>>> >> > 'initialization') -----<br>>>> >> > addControls<br>>>> >> > "Add the control bar at the top of the tool."<br>>>> >> ><br>>>> >> > | b r partsBinButton newButton aWrapper |<br>>>> >> > + newButton := ImageMorph new image: (Project current<br>>>> >> > makeThumbnail scaledToSize: 48@36).<br>>>> >> > - newButton := ImageMorph new image: (World project<br>>>> >> > makeThumbnail scaledToSize: 48@36).<br>>>> >> > newButton on: #mouseDown send: #insertNewProject: to: self.<br>>>> >> > newButton setBalloonText: 'Make a new Project' translated.<br>>>> >> > (partsBinButton := UpdatingThreePhaseButtonMorph checkBox)<br>>>> >> > target: self;<br>>>> >> > actionSelector: #togglePartsBinStatus;<br>>>> >> > arguments: #();<br>>>> >> > getSelector: #getPartsBinStatus.<br>>>> >> > (r := AlignmentMorph newRow)<br>>>> >> > color: Color transparent;<br>>>> >> > borderWidth: 0;<br>>>> >> > layoutInset: 0;<br>>>> >> > cellInset: 10@0;<br>>>> >> > wrapCentering: #center;<br>>>> >> > cellPositioning: #leftCenter;<br>>>> >> > hResizing: #shrinkWrap;<br>>>> >> > vResizing: #shrinkWrap;<br>>>> >> > extent: 5@5.<br>>>> >> > b := SimpleButtonMorph new target: self; color: self<br>>>> >> > defaultColor darker;<br>>>> >> > borderColor: Color black.<br>>>> >> > r addMorphBack: (self wrapperFor: (b label: 'Okay' translated<br>>>> >> > font: ScriptingSystem fontForEToyButtons; actionSelector:<br>>>> >> > #acceptSort)).<br>>>> >> > b := SimpleButtonMorph new target: self; color: self<br>>>> >> > defaultColor darker;<br>>>> >> > borderColor: Color black.<br>>>> >> > r addMorphBack: (self wrapperFor: (b label: 'Cancel'<br>>>> >> > translated font: ScriptingSystem fontForEToyButtons; actionSelector:<br>>>> >> > #delete));<br>>>> >> > addTransparentSpacerOfSize: 8 @ 0;<br>>>> >> > addMorphBack: (self wrapperFor: (newButton));<br>>>> >> > addTransparentSpacerOfSize: 8 @ 0.<br>>>> >> ><br>>>> >> > aWrapper := AlignmentMorph newRow beTransparent.<br>>>> >> > aWrapper cellInset: 0; layoutInset: 0; borderWidth: 0.<br>>>> >> > aWrapper<br>>>> >> > addMorphBack: (self wrapperFor: partsBinButton);<br>>>> >> > addMorphBack: (self wrapperFor: (StringMorph<br>>>> >> > contents: 'Parts bin' translated font: ScriptingSystem<br>>>> >> > fontForEToyButtons) lock).<br>>>> >> > r addMorphBack: aWrapper.<br>>>> >> ><br>>>> >> > self addMorphFront: r.<br>>>> >> > !<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: SpeakerMorph>>addGraphic (in category<br>>>> >> > 'initialization') -----<br>>>> >> > addGraphic<br>>>> >> ><br>>>> >> > | graphic |<br>>>> >> > + graphic := Project current world drawingClass withForm: self<br>>>> >> > speakerGraphic.<br>>>> >> > - graphic := World drawingClass withForm: self speakerGraphic.<br>>>> >> > graphic position: bounds center - (graphic extent // 2).<br>>>> >> > self addMorph: graphic.<br>>>> >> > !<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: SqueakPage>>prePurge (in category 'saving') -----<br>>>> >> > prePurge<br>>>> >> > "Return self if ready to be purged, or nil if not"<br>>>> >> ><br>>>> >> > self isContentsInMemory ifFalse: [^ nil].<br>>>> >> > contentsMorph ifNil: [^ nil]. "out already"<br>>>> >> > url ifNil: [^ nil]. "just to be safe"<br>>>> >> > + ^ (Project current world ~~ nil and: [contentsMorph world ==<br>>>> >> > World])<br>>>> >> > - ^ (World ~~ nil and: [contentsMorph world == World])<br>>>> >> > ifTrue: [nil "showing now"] ifFalse: [self]!<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: TabbedPalette class>>authoringPrototype (in category<br>>>> >> > 'scripting') -----<br>>>> >> > authoringPrototype<br>>>> >> > | aTabbedPalette aBook aTab |<br>>>> >> > aTabbedPalette := self new markAsPartsDonor.<br>>>> >> > aTabbedPalette pageSize: 200 @ 300.<br>>>> >> > aTabbedPalette tabsMorph highlightColor: Color red<br>>>> >> > regularColor: Color blue.<br>>>> >> > aTabbedPalette addMenuTab.<br>>>> >> ><br>>>> >> > aBook := BookMorph new setNameTo: 'one'; pageSize:<br>>>> >> > aTabbedPalette pageSize.<br>>>> >> > aBook color: Color blue muchLighter.<br>>>> >> > aBook removeEverything; insertPage; showPageControls.<br>>>> >> > + aBook currentPage addMorphBack: (Project current world<br>>>> >> > drawingClass withForm: ScriptingSystem squeakyMouseForm).<br>>>> >> > - aBook currentPage addMorphBack: (World drawingClass withForm:<br>>>> >> > ScriptingSystem squeakyMouseForm).<br>>>> >> > aTab := aTabbedPalette addTabForBook: aBook.<br>>>> >> ><br>>>> >> > aBook := BookMorph new setNameTo: 'two'; pageSize:<br>>>> >> > aTabbedPalette pageSize.<br>>>> >> > aBook color: Color red muchLighter.<br>>>> >> > aBook removeEverything; insertPage; showPageControls.<br>>>> >> > aBook currentPage addMorphBack: CurveMorph<br>>>> >> > authoringPrototype.<br>>>> >> > aTabbedPalette addTabForBook: aBook.<br>>>> >> ><br>>>> >> > aTabbedPalette selectTab: aTab.<br>>>> >> ><br>>>> >> > aTabbedPalette beSticky.<br>>>> >> > aTabbedPalette tabsMorph hResizing: #spaceFill.<br>>>> >> > ^ aTabbedPalette!<br>>>> >> ><br>>>> >> > Item was changed:<br>>>> >> > ----- Method: TabbedPalette>>addMenuTab (in category 'palette<br>>>> >> > menu') -----<br>>>> >> > addMenuTab<br>>>> >> > "Add the menu tab. This is ancient code, not much in the<br>>>> >> > spirit of anything current"<br>>>> >> ><br>>>> >> > | aMenu aTab aGraphic sk |<br>>>> >> > aMenu := MenuMorph new defaultTarget: self.<br>>>> >> > aMenu stayUp: true.<br>>>> >> > "aMenu add: 'clear' translated action: #showNoPalette."<br>>>> >> > aMenu add: 'sort tabs' translated action: #sortTabs:.<br>>>> >> > aMenu add: 'choose new colors for tabs' translated action:<br>>>> >> > #recolorTabs.<br>>>> >> > aMenu setProperty: #paletteMenu toValue: true.<br>>>> >> > "aMenu add: 'make me the Standard palette' translated<br>>>> >> > action: #becomeStandardPalette."<br>>>> >> > aTab := self addTabForBook: aMenu withBalloonText: 'a menu<br>>>> >> > of palette-related controls' translated.<br>>>> >> > aTab highlightColor: tabsMorph highlightColor; regularColor:<br>>>> >> > tabsMorph regularColor.<br>>>> >> > tabsMorph laySubpartsOutInOneRow; layoutChanged.<br>>>> >> ><br>>>> >> > aGraphic := ScriptingSystem formAtKey: 'TinyMenu'.<br>>>> >> > aGraphic ifNotNil:<br>>>> >> > [aTab removeAllMorphs.<br>>>> >> > + aTab addMorph: (sk := Project current world<br>>>> >> > drawingClass withForm: aGraphic).<br>>>> >> > - aTab addMorph: (sk := World drawingClass withForm:<br>>>> >> > aGraphic).<br>>>> >> > sk position: aTab position.<br>>>> >> > sk lock.<br>>>> >> > aTab fitContents].<br>>>> >> > self layoutChanged!<br>>>> >> ><br>>>> >> ><br>>>> >><br>>>><br>>><br>>><br>><br>><br>><br>><br><br></hannes.hirzel@gmail.com></marcel.taeumel@hpi.de>
                        </blockquote>
                                        </div></body>