The Question Mark - blog by Mark Volkmann

Does Not Understand

The Object class defines the doesNotUnderstand: method which opens a MessageNotUnderstood window. This can be overridden in specific classes to provide specialized processing of messages that do not have corresponding methods.

Let’s demonstrate this by defining an Accessible class that enables sending messages to set and get any instance variable in classes that inherit from this class.

Here is the class definition:

Object subclass: #Accessible
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Volkmann'

Here is its one and only instance method:

doesNotUnderstand: aMessage
    "gets or sets an instance variable"

    | argCount getters index key setters |

    "We are only processing messages with 0 or 1 arguments.
    If there are 2 or more arguments, fall back to the default behavior."
    argCount := aMessage numArgs.
    argCount > 1 ifTrue: [^super doesNotUnderstand: aMessage].

    key := aMessage keywords first.

    "If the message is a getter, return the
    corresponding instance variable value."
    getters := self class allInstVarNames.
    index := getters indexOf: key.
    index ifNotZero: [^self instVarAt: index].

    "If the message is a setter, set the
    corresponding instance variable value."
    setters := getters collect: [:name | name, ':'].
    index := setters indexOf: key.
    index ifNotZero: [^self instVarAt: index put: aMessage arguments first ].

    "Otherwise fall back to the default behavior."
    ^super doesNotUnderstand: aMessage

Here is an example subclass of Accessible:

Accessible subclass: #Person
    instanceVariableNames: 'birthdate firstName lastName'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'Volkmann'

Here is an example of using this class:

p := Person new.
p firstName: 'Mark'.
p firstName print. "Mark"

Getting and setting instance variables in this way is quite inefficient. A better approach is to generate accessor methods by right-clicking the Person class in a System Browser and selecting “more…create inst var accessors” to generate accessor methods for each instance variable.