Tony Garnock-Jones uploaded a new version of Environments to project The Inbox:
http://source.squeak.org/inbox/Environments-tonyg.78.mcz ==================== Summary ==================== Name: Environments-tonyg.78 Author: tonyg Time: 25 March 2021, 1:41:26.338334 pm UUID: 1f57f26d-c9da-4c95-adb3-3fd76774a64d Ancestors: Environments-dtl.77 EXPERIMENTAL. Nested `Namespace`s, by introducing subclass Namespace of Environment, and placing Namespace instances as "globals" in their parent environment. See also Tools-tonyg.1033, which includes an experimental EnvironmentBrowser class. =============== Diff against Environments-dtl.77 =============== Item was changed: + SystemOrganization addCategory: #'Environments-Help'! SystemOrganization addCategory: #'Environments-Core'! SystemOrganization addCategory: #'Environments-Loading'! - SystemOrganization addCategory: #'Environments-Policies'! - SystemOrganization addCategory: #'Environments-Help'! SystemOrganization addCategory: #'Environments-Notifications'! + SystemOrganization addCategory: #'Environments-Policies'! + SystemOrganization addCategory: #'Environments-Namespaces'! Item was added: + ----- Method: Environment class>>wellKnownInstances (in category 'as yet unclassified') ----- + wellKnownInstances + ^ Instances values sorted: [:a :b | + (a info name = #Smalltalk) + ifTrue: [true] ifFalse: [ + (b info name = #Smalltalk) + ifTrue: [false] ifFalse: [ + a info name <= b info name]]]! Item was added: + ----- Method: Environment>>isNamespace (in category 'testing') ----- + isNamespace + ^ false! Item was added: + ----- Method: Environment>>namespacePath (in category 'accessing') ----- + namespacePath + ^ Array with: self! Item was added: + ----- Method: Environment>>namespaceTreeDo: (in category 'accessing') ----- + namespaceTreeDo: aBlock + aBlock value: self. + self namespaces do: [:ns | ns namespaceTreeDo: aBlock].! Item was added: + ----- Method: Environment>>namespaces (in category 'accessing') ----- + namespaces + "Answer all Environments declared here whose parent is this Environment" + | nss | + nss := self select: [:item | + (item value isKindOf: Environment) and: [item value parent == self]]. + nss := nss asArray collect: [:item | item value]. + nss sort: [:a :b | (a name compare: b name) <= 2]. + ^ nss! Item was added: + ----- Method: Environment>>parent (in category 'accessing') ----- + parent + ^ nil! Item was added: + ----- Method: Environment>>rename: (in category 'accessing') ----- + rename: newName + | wellKnown | + newName = info name ifTrue: [^ self]. + (wellKnown := Instances includes: self) ifTrue: [ + (Instances anySatisfy: [:e | newName = e info name]) + ifTrue: [self error: 'Name collision: well-known Environment with name ', newName, ' already exists']]. + wellKnown ifTrue: [Instances removeKey: info name]. + info rename: newName. + wellKnown ifTrue: [Instances at: newName put: self].! Item was added: + ----- Method: EnvironmentInfo>>rename: (in category 'private') ----- + rename: newName + name := newName! Item was added: + Environment subclass: #Namespace + instanceVariableNames: 'parent' + classVariableNames: '' + poolDictionaries: '' + category: 'Environments-Namespaces'! Item was added: + ----- Method: Namespace>>checkName:in: (in category 'namespace hierarchy') ----- + checkName: name in: parent + (parent notNil and: [(parent at: name ifAbsent: [self]) ~~ self]) + ifTrue: [self error: 'Name collision: proposed name ', name, ' in ', parent name, ' for namespace ', self name, ' is already taken'].! Item was added: + ----- Method: Namespace>>doesNotUnderstand: (in category 'dynamic lookup') ----- + doesNotUnderstand: aMessage + aMessage numArgs = 0 ifFalse: [^ super doesNotUnderstand: aMessage]. + ^ self valueOf: aMessage selector ifAbsent: [^ super doesNotUnderstand: aMessage]! Item was added: + ----- Method: Namespace>>initialize (in category 'initialize-release') ----- + initialize + super initialize. + self importSelf. + self import: Environment default.! Item was added: + ----- Method: Namespace>>isNamespace (in category 'as yet unclassified') ----- + isNamespace + ^ true! Item was added: + ----- Method: Namespace>>namespacePath (in category 'namespace hierarchy') ----- + namespacePath + | e | + e := self. + ^ (Array streamContents: [:w | + [e notNil and: [e isNamespace]] whileTrue: [ + w nextPut: e. + e := e parent]]) reverseInPlace! Item was added: + ----- Method: Namespace>>parent (in category 'accessing') ----- + parent + ^ parent! Item was added: + ----- Method: Namespace>>parent: (in category 'accessing') ----- + parent: anEnvironment + | n | + parent == anEnvironment ifTrue: [^self]. + n := info name asSymbol. + self checkName: n in: anEnvironment. + parent ifNotNil: [parent removeKey: n]. + parent := anEnvironment. + parent ifNotNil: [parent at: n put: self].! Item was added: + ----- Method: Namespace>>printOn: (in category 'printing') ----- + printOn: aStream + self namespacePath do: [:n | aStream nextPutAll: n info name] separatedBy: [aStream space]! Item was added: + ----- Method: Namespace>>rename: (in category 'accessing') ----- + rename: newName + | p | + p := parent. + self checkName: newName in: p. + self parent: nil. + super rename: newName. + self parent: p.! Item was added: + ----- Method: Namespace>>respondsTo: (in category 'dynamic lookup') ----- + respondsTo: aSymbol + ^ (super respondsTo: aSymbol) or: [self includesKey: aSymbol]! |
Hi all,
This message is about the in-inbox EXPERIMENTAL DRAFT packages - http://source.squeak.org/inbox/Environments-tonyg.78.mcz and - http://source.squeak.org/inbox/Tools-tonyg.1033.mcz The two packages go together. Screenshot of EnvironmentBrowser in action attached. The idea here is a kind of Self-like "namespacing" facility, based around placing Environment instances into another Environment's globals table. The EnvironmentBrowser class in Tools 1033 is a sketch of UI for the core functionality I've identified so far. If I have the following setup of nested Environments... Smalltalk -- the normal Environment default / Environment current - A - B - C - D with class X in A, class Y in B, a *different* class Y in C, and class Z in D, then - In a workspace whose environment is Smalltalk, `A` evaluates to the environment A. `A B` evaluates to the environment B. `A B Y` evaluates to B's Y. `A C Y` evaluates to C's Y. etc. - In a workspace whose environment is A, all of the examples from the Smalltalk paragraph above are unchanged `B` evaluates to the environment B, `B Y` yields B's Y `C Y` yields C's Y `D` is an undefined name - In a workspace whose environment is B, all of the examples from the Smalltalk paragraph above are unchanged `Y` is B's Y `C` and `D` are undefined names The ability of Environments to import/export is unused (!) at present, other than Namespace instances default to importing self and Smalltalk. I'm looking at Monticello now. The major difficulty is that it hardcodes `Environment current` and expects a single environment to apply. I imagine the following: - the nested namespaces are analogous to nested folders in a Unix file system - packages are like Debian packages, and may have entries in multiple namespaces - `Environment current` at load time acts like a chroot Given those guesses/assumptions, MC might need to learn about the idea of classes living in a particular (or more than one!) Environment, and the necessity of creating Namespaces as needed. Here's an interesting method on PackageInfo I've been messing around with: classesAndEnvironments | cs | cs := IdentityDictionary new. self systemCategories do: [:cat | Environment current namespaceTreeDo: [:environment | (environment organization listAtCategoryNamed: cat) do: [:className | | envs | envs := cs at: (environment valueOf: className) ifAbsentPut: [Set new]. envs add: environment]]]. ^ cs Does anyone have thoughts on this whole approach? On how MC's model could profitably be altered to include a notion of namespace/environment? Regards, Tony Environment Browser on E F: NamespacedExampleClass.png (53K) Download Attachment Workspace on environment E F.png (14K) Download Attachment |
Hi Tony,
if I would implement a hierarchy of environments, I would not exploit "globals" or "declarations" but add "outer" and/or "inner" as instance variables. Then #classNamed: needs to be changed to also look in outer environments. -- I think that environments are already "namespaces". Thus, I would not add an extra subclass "Namespace" for it. The second proposal in here is that new syntax via #doesNotUnderstand:. Hmm... I do not like it. :-) Maybe a Environment class >> #fromPath: would work. Then tools can support such a path syntax. In source code I would rather not use it to not create any more "spaghetti code" than we already have. Feels like a "pandoras box" to allow an easy way for arbitrary environments in any piece of code. Best, Marcel
|
-1 on the #doesNotUnderstand: proposal. JsonObject is already questionable depending on the use case - IMHO message forwarding is easy to abuse, and using it for any kind of lookup appears kind of abusive to me. However, only my 2 cents. :-)
A big +1 for the rest of the proposed changes! :-)
Best, Christoph Von: Squeak-dev <[hidden email]> im Auftrag von Taeumel, Marcel
Gesendet: Freitag, 26. März 2021 11:42:24 An: squeak-dev Betreff: Re: [squeak-dev] EnvironmentBrowser and nested Namespaces (was Re: The Inbox: Environments-tonyg.78.mcz)
Hi Tony,
if I would implement a hierarchy of environments, I would not exploit "globals" or "declarations" but add "outer" and/or "inner" as instance variables. Then #classNamed: needs to be changed to also look in outer environments. -- I
think that environments are already "namespaces". Thus, I would not add an extra subclass "Namespace" for it.
The second proposal in here is that new syntax via #doesNotUnderstand:. Hmm... I do not like it. :-) Maybe a Environment class >> #fromPath: would work. Then tools can support such a path syntax. In source code I would rather not use it to not create any
more "spaghetti code" than we already have. Feels like a "pandoras box" to allow an easy way for arbitrary environments in any piece of code.
Best,
Marcel
Carpe Squeak!
|
Free forum by Nabble | Edit this page |