Monday, April 25, 2011

Why does e.g. Object inheritsFrom: fooobaar return true in Smalltalk?

It seems that the inheritsFrom: method in GNU Smalltalk returns true for every undefined class name sent to it as a parameter. This might make a program very hard to debug, IMHO. Looking at the code for this in the Behavior class, it looks like this:

inheritsFrom: aClass [
"Returns true if aClass is a superclass of the receiver"

<category: 'testing the class hierarchy'>
| sc |
aClass isNil ifTrue: [^true].

sc := self.
[sc := sc superclass.
sc isNil] whileFalse: [sc == aClass ifTrue: [^true]].
^false
]

The line aClass isNil ifTrue: [^true] is the culprit, but I am looking for a sane reason as to way it was coded this way. (I am new to the Smalltalk world, by the way, and trying to learn.)

Thanks.

From stackoverflow
  • I suppose the thinking is that all class references must imply a class of some sort so the nil reference implies Object, which is the superclass of everything.

    Squeak does it more the way you'd expect:

    inheritsFrom: aClass 
    
    |aSuperclass |
    aSuperclass := superclass.
    [aSuperclass == nil]
     whileFalse: [aSuperclass == aClass
       ifTrue: [^ true].
      aSuperclass := aSuperclass superclass].
    ^ false
    

    link text

    Eyvind : While you are right that this is closer to my expectation, what I really would expect though was that there would be an exception thrown.
    anon : Smalltalk traditionally doesn't use exceptions very much.
  • This is not related to exceptions but rather to undefined variables. In GNU Smalltalk's REPL, or alternatively in a Transcript or Workspace for graphical environments, undefined variables are all nil---this is not very different in Ruby, for example.

    So you are doing in fact "Object inheritsFrom: nil", which is true. I didn't know it is false in Squeak; that would be a departure from the Blue Book, actually.

    In a method, you would have gotten a "variable fooobaar undefined" compile-time error.

    Paolo Bonzini : Hum, Neil's answer (which I cannot comment directly) is wrong in that Object is not the superclass of everything. In some sense, nil is the superclass of everything -- the Autoload class of GNU Smalltalk for example inherits directly from nil, not from Object, and there are many other examples.

0 comments:

Post a Comment