"====================================================================== | | Namespace Method Definitions | | $Revision: 1.7.5$ | $Date: 2000/05/28 16:56:52$ | $Author: pb$ | ======================================================================" "====================================================================== | | Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc. | Written by Paolo Bonzini. | | This file is part of the GNU Smalltalk class library. | | The GNU Smalltalk class library is free software; you can redistribute it | and/or modify it under the terms of the GNU Lesser General Public License | as published by the Free Software Foundation; either version 2.1, or (at | your option) any later version. | | The GNU Smalltalk class library is distributed in the hope that it will be | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | General Public License for more details. | | You should have received a copy of the GNU Lesser General Public License | along with the GNU Smalltalk class library; see the file COPYING.LESSER. | If not, write to the Free Software Foundation, 59 Temple Place - Suite | 330, Boston, MA 02111-1307, USA. | ======================================================================" RootNamespace variableSubclass: #Namespace instanceVariableNames: '' classVariableNames: 'Current' poolDictionaries: '' category: 'Language-Implementation' ! Namespace comment: 'I am a special form of dictionary. I provide special ways to access my keys, which typically begin with an uppercase letter. Classes hold on an instance of me; it is called their `environment''). My keys are (expected to be) symbols, so I use == to match searched keys to those in the dictionary -- this is done expecting it brings a bit more speed.' ! !Namespace class methodsFor: 'disabling instance creation'! new "Disabled - use #addSubspace: to create instances" ^self error: 'use #addSubspace: to create instances' ! new: size "Disabled - use #addSubspace: to create instances" ^self error: 'use #addSubspace: to create instances' ! ! !Namespace methodsFor: 'accessing'! inheritedKeys "Answer a Set of all the keys in the receiver and its superspaces" ^self keys removeAll: self definedKeys ifAbsent: [ :each | self error: 'huh?!? synchronization problem?!?' ]; yourself ! ! !Namespace methodsFor: 'overrides for superspaces'! associationsDo: aBlock "Pass each association in the namespace to aBlock" self allAssociations associationsDo: aBlock ! at: key ifPresent: aBlock "If aKey is absent from the receiver and all its superspaces, answer nil. Else, evaluate aBlock passing the associated value and answer the result of the invocation" | index space | space := self. [ index := space findIndexOrAnswerNil: key. index isNil ] whileTrue: [ space := space superspace. space isNil ifTrue: [ ^nil ]. ]. ^aBlock value: (space primAt: index) value ! associationAt: key ifAbsent: aBlock "Return the key/value pair associated to the variable named as specified by `key'. If the key is not found search will be brought on in superspaces, finally evaluating aBlock if the variable cannot be found in any of the superspaces." | index space | space := self. [ index := space findIndexOrAnswerNil: key. index isNil ] whileTrue: [ space := space superspace. space isNil ifTrue: [ ^aBlock value ]. ]. ^(space primAt: index) value ! at: key ifAbsent: aBlock "Return the value associated to the variable named as specified by `key'. If the key is not found search will be brought on in superspaces, finally evaluating aBlock if the variable cannot be found in any of the superspaces." | index space | space := self. [ index := space findIndexOrAnswerNil: key. index isNil ] whileTrue: [ space := space superspace. space isNil ifTrue: [ ^aBlock value ]. ]. ^(space primAt: index) value ! do: aBlock "Pass each value in the namespace to aBlock" self allAssociations do: aBlock ! includesKey: key "Answer whether the receiver or any of its superspaces contain the given key" | index space | space := self. [ index := space findIndexOrAnswerNil: key. index isNil ] whileTrue: [ space := space superspace. space isNil ifTrue: [ ^false ]. ]. ^true ! keysAndValuesDo: aBlock "Pass to aBlock each of the receiver's keys and values, in two separate parameters" self allAssociations keysAndValuesDo: aBlock ! keysDo: aBlock "Pass to aBlock each of the receiver's keys" self keys do: aBlock ! set: key to: newValue ifAbsent: aBlock "Assign newValue to the variable named as specified by `key'. This method won't define a new variable; instead if the key is not found it will search in superspaces and evaluate aBlock if it is not found. Answer newValue." | index space | space := self. [ index := space findIndexOrAnswerNil: key. index isNil ] whileTrue: [ space := space superspace. space isNil ifTrue: [ ^aBlock value ]. ]. (space primAt: index) value: newValue. ^newValue ! size "Answer the number of keys in the receiver and each of its superspaces" ^super size + self superspace size ! ! !Namespace methodsFor: 'namespace hierarchy'! siblings "Answer all the other namespaces that inherit from the receiver's superspace." ^self superspace subspaces copy remove: self; yourself ! siblingsDo: aBlock "Evaluate aBlock once for each of the other namespaces that inherit from the receiver's superspace, passing the namespace as a parameter." self superspace subspaces do: [ :space | space == self ifFalse: [ aBlock value: space ] ] ! ! !Namespace methodsFor: 'printing'! name "Answer the receiver's name" ^(self superspace keyAtValue: self ifAbsent: [ ^self defaultName ]) asString ! storeOn: aStream "Store Smalltalk code compiling to the receiver" | result name | name := self name. name = '' ifTrue: [ self error: 'cannot print unnamed namespace' ]. self superspace storeOn: aStream. aStream space; nextPutAll: name ! !