Namespace current: aSymbol

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Namespace current: aSymbol

S11001001
I often make the silly mistake of passing a symbol as argument to
Namespace class>>#current:.  I wouldn't normally want kernel methods
to do explicit checks for errors like this, except that backtraces
that mention classes outside the current namespace-and-supers chain
can cause infinite recursion in the backtrace printing.

Try it out:

st> Namespace current addSubspace: #Test!

st> Namespace current: #Test!

st> (#(1 2 3) detect: [:each | each = 4]) qqq!
Object: Collection error: Invalid argument nil: object not found
Smalltalk.Collection class(Smalltalk.Object)>>#primError:
Object: #SystemExceptions error: did not understand #between:and:
Smalltalk.Symbol(Smalltalk.Object)>>#primError:
Smalltalk.MessageNotUnderstood(Smalltalk.Exception)>>#defaultAction
optimized [] in Smalltalk.Exception class>>#coreException
Smalltalk.MessageNotUnderstood(Smalltalk.Signal)>>#activateHandler:
Smalltalk.MessageNotUnderstood(Smalltalk.Exception)>>#signal
Smalltalk.Symbol(Smalltalk.Object)>>#doesNotUnderstand:
Smalltalk.Symbol(Smalltalk.SequenceableCollection)>>#at:ifAbsent:
Smalltalk.Namespace>>#printOn:in:
<repeat last 9 lines ad infinitum>

The primitive for Namespace class>>#current: appears to ignore its
argument if it is not a Dictionary or Class.  Perhaps the Smalltalk
code that follows it should do the same, or signal an error of some
kind, if aNamespaceOrClass is not in fact a BindingDictionary (or
Dictionary) or Class?

Or maybe I should just write an extra check for isKindOf: Array in my
local copy.  :)

--
Stephen Compall
http://scompall.nocandysw.com/blog


_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk
Reply | Threaded
Open this post in threaded view
|

Re: Namespace current: aSymbol

Paolo Bonzini

> The primitive for Namespace class>>#current: appears to ignore its
> argument if it is not a Dictionary or Class.  Perhaps the Smalltalk
> code that follows it should do the same, or signal an error of some
> kind, if aNamespaceOrClass is not in fact a BindingDictionary (or
> Dictionary) or Class?
Yep, as in the attached patch.

Paolo

--- orig/kernel/Builtins.st
+++ mod/kernel/Builtins.st
@@ -2585,10 +2585,18 @@ current: aNamespaceOrClass
     "Set the current namespace to be aNamespace or, if it is a class,
      its class pool (the Dictionary that holds class variables)."
     "The primitive call is needed to inform the compiler"
+    | namespace |
     <primitive: VMpr_Namespace_setCurrent>
-    Current := aNamespaceOrClass isClass
+    namespace := aNamespaceOrClass isClass
  ifTrue: [ aNamespaceOrClass classPool ]
  ifFalse: [ aNamespaceOrClass ].
+
+    (namespace isKindOf: Dictionary)
+ ifTrue: [ Current := namespace ]
+ ifFalse: [
+    SystemExceptions.WrongClass
+ signalOn: aNamespaceOrClass
+ mustBe: { Dictionary. Class } ].
 ! !
 
 
--- orig/kernel/AnsiExcept.st
+++ mod/kernel/AnsiExcept.st
@@ -1083,14 +1083,16 @@ validClassesString
     "Answer the list of classes whose instances would have been valid,
     formatted as a string."
     ^String streamContents: [ :str |
- validClasses keysAndValuesDo: [ :idx :binding |
+ validClasses keysAndValuesDo: [ :idx :classOrBinding |
     | name class |
     idx > 1 ifTrue: [
  idx = validClasses size
     ifFalse: [ str nextPutAll: ', ' ]
     ifTrue: [ str nextPutAll: ' or ' ]
     ].
-    class := binding value.
+    class := classOrBinding isClass
+ ifTrue: [ classOrBinding ]
+ ifFalse: [ classOrBinding value ].
     name := class nameIn: Namespace current.
     name first isVowel
  ifTrue: [ str nextPutAll: 'an ' ]

_______________________________________________
help-smalltalk mailing list
[hidden email]
http://lists.gnu.org/mailman/listinfo/help-smalltalk