[comp.sys.next] Debugging objects and connections

feldman@umd5.umd.edu (Mark Feldman) (02/02/89)

Objective C (obj-C), the Interface Builder (IB), and runtime binding (RB),
without a doubt, make writing applications and incorporating previously
created objects relatively easy.  Non-programmers or, at least, ``light
weight programmers'' can connect objects and create interfaces without
having to know the underlying obj-C.  If you have an object and know its
actions and outlets (input and output messages), NeXT provides a wondeful
erector set-like environment.  

The problem that I have run into is what happens when there are obj-C RB
problems.  What happens when certain connections are not made or actions
contain typos or use the wrong parameters?  You have to become a programmer
to find the problem -- that's what.

When writing one application, I accidentally put a space in the name of an
action for an object that I was creating.  The space wasn't very noticable
in IB because of the font being used.  Proportional fonts are great things...
for some applications.  I couldn't figure out why the input to the interface
wasn't getting to my object.  I would like to see a way of trapping messages
sent off to space without being forced to use the the GNU debugger (gdb).
I'm not putting down gdb, I just don't think that gdb is an appropriate tool
for people doing little or no progamming, just connecting objects.

If you write and distribute product-quality objects that will be integrated
into other applications -- one of the goals of NeXT, obj-C, and object
oriented programming in general -- your objects should be robust and be able
to operate around a poorly formed environment, failing gracefully when other
needed objects do not exist or do not make use of the actions and parameters
that you think that they should.  An example is in order...

I write and distribute an object called foobar (don't you just love
realistic examples?).  A foobar undestands the method foo and it talks to an
outlet called bar.  The message that a foobar sends to its bar outlet is
setStringValue.  If someone uses (buys?) my foobar and either forgets to
connect its bar outlet or connects it to something that doesn't understand
setStringValue, they will be at a loss if things stay as they are.  I would
like to trap the fact that [bar setStringValue:myString] went off into space
or was not understood and have the chance to take corrective action.
Perhaps my corrective action would be nothing more than to put up a small
window explaining what had gone wrong in English.  

Ideas?  Comments?  Large sums of money?

	Mark

gore@eecs.nwu.edu (Jacob Gore) (02/02/89)

/ comp.sys.next / feldman@umd5.umd.edu (Mark Feldman) / Feb  1, 1989 /
>I would
>like to trap the fact that [bar setStringValue:myString] went off into space
>or was not understood and have the chance to take corrective action.
>Perhaps my corrective action would be nothing more than to put up a small
>window explaining what had gone wrong in English.  
>
>Ideas?

I'm afraid I'm in no position to test this at the moment, and my
Objective-C manual and knowledge are a couple of years old.  But you did
ask for ideas, so:

Here's what that old manual says in the listing of methods for class Object
(which every other class inherits from, directly or transitively):

	-doesNotRecognize:(STR)aMessage
		The message routine reports that the receiver did not
		recognize aMessage by sending 'doesNotRecognize:aMessage'
		to the receiver instead.  It is defined as:

		return [self error:"%s does not recognize %s",
			     NAMEOF(self), aMessage]

In plain English, this means that what happens in your example is that
'[bar doesNotRecognize:"setStringValue"]' is done, and 'bar' probably deals
with it according to the "doesNotRecognize:" method it inherited from class
Object (unless some class in between bar's class and class Object
redeclared that method, in which case bar's class, of course, would inherit
it from there).

So, all you have to do is provide your own "doesNotRecognize:(STR)aMessage"
method to 'bar', either in the definition of its class, or in the
definition of one of its superclasses.

If the current implementation of Objective-C supports multiple inheritance,
the best way to handle this is to create a class, say, NotRecognizedPanel,
which defines "doesNotRecognize:" to pop up one of those error panels with
OK/Cancel/etc. choices.  Then bar's class can just add NotRecognizedPanel
to the list of its superclasses.

Inheritance is fun.

Jacob Gore				Gore@EECS.NWU.Edu
Northwestern Univ., EECS Dept.		{oddjob,gargoyle,att}!nucsrl!gore