Replacing doits in modules

Henrik Gedenryd h.gedenryd at open.ac.uk
Mon Mar 25 09:01:54 UTC 2002


Jim, 

sorry for taking so long to answer. I've been very busy.

Gran  Hultgren wrote:

>> Hi,
>> 
>> Well, I finally bit the bullet and tried to convert some of my code to
>> modules in 3.3.
>> 
>> Let me start again. A small green puppet with a voice like Fozi Bear once
>> said:
>> 
>> "Do, or do not. There is no try"

I know. He rarely wins in my head either. He kept telling me not to do the
modules thing. ;-) And he was probably right, but that doesn't have to do
with your questions.

>> In my case, I did not get my code to work. I have a few questions to ask.
>> 
>> Since doits are not allowed in the module code, how do you go about doing
>> things in that have been traditionally done in a changeset's postscript?
>> 
>> I'm the first to admit, my code does some pretty nasty things. As an
>> example, I want to take the base class SystemWindow, add an instance
>> variable to it, and then run a conversion on all existing instances to fill
>> in the new instance with proper values. In a previous life in the changeset
>> world, I would put in the postscript something along the lines of:
>> 
>> SystemWindow allInstances do: [ :aWindow | aWindow convertLabelToFrame ].
>> 
>> How do I do this in the modules world?
> 
> I would guess, as it is now, you would have to fall back on class
> initialization. It's currently
> done after the modules has been loaded and activated.

Jim, as you say, this is a pretty advanced thing to do. It's even so far out
on the end of things that one might want to do that it has hardly been
discussed here. And you know this list--merely being far out doesn't stop
any discussions here, so this is very far down on the list.

The correct answer would be that this is an issue for DeltaModules, and one
of the trickiest. Modules as such only deal with dead code, not running
programs. For that reason modularity as we know it on this planet has hardly
dealt with the issue of migrating a running system, so I think we'll have to
invent the answer ourselves if we want one.

Some options:

- A separate class that migrates the existing instances. A clean general
solution but probably a little too heavy-weight.

- Use class methods somewhere to do the job. Uglier but lighter.

- Make modules be classes. A little bit over-engineered IMO.

- Give DeltaModules pre- and postscript annotations. Not an unreasonable
solution.

In short you are pushing the system a little bit beyond the curve at this
point. DMs just aren't that advanced yet. We have all grown used to doing
pretty advanced/nasty things as part of our normal coding.

>> Which leads me to the second question:
>> 
>> In addition to defining classes and methods, my changesets also tend to
>> instantiate objects and populate them with data, again part of the changeset
>> postscript. I do a lot of things like create an object, and place some
>> bitmaps read from disk into them, or create a class variable that is a
>> Dictionary and fill it with defaults. How do things like that get handled in
>> the new world order?
> I still would guess in class initialization. Henrik?

This sounds like code that more naturally fits into class initialization
code. Yes/no?

> 
>> Which goes into the third question:
>> 
>> Trying to upload my code, I get the DNU "The attempt to declare used modules
>> from referenced global names did not completely succeed. (There may be
>> Undeclared references.)". While I appreciate the candor of the error
>> message, I can't say that I know how to go about fixing the problem. Looking
>> at the code that I've filed in, it seems pretty straightforward. How do I go
>> about figuring out what the Undeclared references are?

Right. This auto-declaration has been discussed before. In short it can't be
perfect.

Select your module in a ModuleExplorer and execute "self
viewDeepUnresolvedRefs". This lists all methods using unresolved global
variables.

You check for Undeclared variables using the usual tools in the World's
"do..." menu.

It's hard to give better help without seeing the code, send it to me and
I'll have a look.

> 
>> Fourth question:
>> 
>> I file in a changeset which redefines SystemWindow>>initialize. This works
>> correctly. I fiddle around with several more changesets, and then redefine
>> SystemWindow>>initialize again. After filing in the first changeset,
>> SystemWindow>>initialize is redefined, both in
>> 
>> category: 'Morphic-Library-Windows'
>> 
>> and:
>> 
>> category: 'Project-Zurgle-Squeak Morphic Library Windows delta'
>> 
>> However, when the second changeset is read in, the #initialize in
>> 'Morphic-Library-Windows' remains the same as when the first changeset was
>> read in, and the #initialize in 'Project-Zurgle-Squeak Morphic Library
>> Windows delta' changes to be the same as in the second changeset. The second
>> changesets #initialize never gets called, which tends to put a damper on
>> what would otherwise be a pretty happy afair.

I guess you are running the conversion method here, since it generates a
DeltaModule (the second one). I'll admit I haven't written it to handle
successive change sets that modify the same classes/methods. Can you explain
why you don't do it all in one change set? That will help me give a sensible
suggestion.

In all, Jim, you've been quite brave and really pushed the envelope. The
system is not at the point where it can handle deep modifications to the
existing system. It does however handle separate packages with reasonably
simple modifications to the base image, such as Connectors or Comanche.

I think the best solution will be to allow modules to specify "extra files"
to be filed in. This will allow various fringe cases to be handled more
reasonably.

Henrik




More information about the Squeak-dev mailing list