problem with filein

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

problem with filein

Jecel Assumpcao Jr
Yesterday Lawson was having problems trying to file in code he had
exported from another image. All the instance methods from one of the
classes were missing - the browser showed them but when you clicked on
them the code pane remained blank. The class methods were ok, as was a
different class.

It took me a while to track down what was happening (single stepping
through logic mixed in a wierd way with gui code is tricky). The same
thing happened in both 4.1 and 3.10.2 and was a combination of things:

1) the class was defined as a subclass of something that was not in the
image, so the system was silently making it a subclass of ProtoObject
instead (though the browser said it was a subclass of Object - very
odd). Didn't we have a warning for this situation?

2) the last expression in the filein sent #initialize to the new class

3) the first line of the class method #initialize was "super
initialize."

4) due to the wrong superclass structure, this invoked the instance
method #initialize in Behavior

5) the first line in that method is "self methodDictionary: self
emptyMethodDictionary."

So the file in had actually worked just fine, but at this point deleted
all the instance methods that had just been created. This might cause
problems for others, but I didn't call it a "bug" since each part is
correct in itself. Perhaps there should be a warning for 1? I imagine
that would be annoying and even scary when loading stuff out of order.

-- Jecel


Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Andreas.Raab
On 8/12/2010 10:44 AM, Jecel Assumpcao Jr. wrote:
> So the file in had actually worked just fine, but at this point deleted
> all the instance methods that had just been created. This might cause
> problems for others, but I didn't call it a "bug" since each part is
> correct in itself. Perhaps there should be a warning for 1? I imagine
> that would be annoying and even scary when loading stuff out of order.

What do you think about implementing ProtoObject class>>initialize as an
empty stub? This would act as a backstop for situations like these.

Cheers,
   - Andreas

Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Bert Freudenberg

On 12.08.2010, at 20:48, Andreas Raab wrote:

> On 8/12/2010 10:44 AM, Jecel Assumpcao Jr. wrote:
>> So the file in had actually worked just fine, but at this point deleted
>> all the instance methods that had just been created. This might cause
>> problems for others, but I didn't call it a "bug" since each part is
>> correct in itself. Perhaps there should be a warning for 1? I imagine
>> that would be annoying and even scary when loading stuff out of order.
>
> What do you think about implementing ProtoObject class>>initialize as an empty stub? This would act as a backstop for situations like these.

It should not be empty but an error message "Never send initialize to super on the class side!"

- Bert -


Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Jecel Assumpcao Jr
Bert Freudenberg wrote on Thu, 12 Aug 2010 21:20:15 +0200

> On 12.08.2010, at 20:48, Andreas Raab wrote:
>
> > On 8/12/2010 10:44 AM, Jecel Assumpcao Jr. wrote:
> >> So the file in had actually worked just fine, but at this point deleted
> >> all the instance methods that had just been created. This might cause
> >> problems for others, but I didn't call it a "bug" since each part is
> >> correct in itself. Perhaps there should be a warning for 1? I imagine
> >> that would be annoying and even scary when loading stuff out of order.
> >
> > What do you think about implementing ProtoObject class>>initialize as
> > an empty stub? This would act as a backstop for situations like these.
>
> It should not be empty but an error message "Never send initialize to
> super on the class side!"

This sounds good. Currently, ProtoObject has a single class method
(#initializedInstance) and I think it normally does its job (supporting
proxies and shared behavior between normal objects and nil) through
instance side methods.

Looking at the class side implementors of #initialize (out of the 764 in
this 4.1 image with Celeste) I see that only CornerGripMorph,
DateAndTime and TestCase do "super initialize". None of these would be
harmed by this change. Object class has an #initialize, so you do have
to be a subclass of ProtoObject to run into problems..

-- Jecel


Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Randal L. Schwartz
In reply to this post by Jecel Assumpcao Jr
>>>>> "Jecel" == Jecel Assumpcao <[hidden email]> writes:

Jecel> 1) the class was defined as a subclass of something that was not in the
Jecel> image, so the system was silently making it a subclass of ProtoObject
Jecel> instead (though the browser said it was a subclass of Object - very
Jecel> odd). Didn't we have a warning for this situation?

I can't imagine any case where

  Foo subclass: #Bar [...]

should *succeed* if Foo doesn't exist.  Can you explain why this isn't fatal?

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[hidden email]> <URL:http://www.stonehenge.com/merlyn/>
Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc.
See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion

Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Jecel Assumpcao Jr
Randal L. Schwartz wrote on Date: Thu, 12 Aug 2010 12:46:52 -0700

> Jecel> 1) the class was defined as a subclass of something that was not in the
> Jecel> image, so the system was silently making it a subclass of ProtoObject
> Jecel> instead (though the browser said it was a subclass of Object - very
> Jecel> odd). Didn't we have a warning for this situation?
>
> I can't imagine any case where
>
>   Foo subclass: #Bar [...]
>
> should *succeed* if Foo doesn't exist.  Can you explain why this isn't fatal?

Indeed, I would expect the compiler to refuse to accept this code since
it can't know what to do with "Foo". But I am guessing that somehow that
is being silently converted into a translation to nil instead.
UndefinedObject does have a
#subclass:instanceVariableNames:classVariableNames:poolDictionaries:cate
gory: instance method to deal with legacy code that has the hack "nil
subclass: #Bar ..." to implement proxies and stuff - it just now
redirects it to the proper ProtoObject class.

-- Jecel


Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

LawsonEnglish
In reply to this post by Bert Freudenberg
On 8/12/10 12:20 PM, Bert Freudenberg wrote:

> On 12.08.2010, at 20:48, Andreas Raab wrote:
>
>    
>> On 8/12/2010 10:44 AM, Jecel Assumpcao Jr. wrote:
>>      
>>> So the file in had actually worked just fine, but at this point deleted
>>> all the instance methods that had just been created. This might cause
>>> problems for others, but I didn't call it a "bug" since each part is
>>> correct in itself. Perhaps there should be a warning for 1? I imagine
>>> that would be annoying and even scary when loading stuff out of order.
>>>        
>> What do you think about implementing ProtoObject class>>initialize as an empty stub? This would act as a backstop for situations like these.
>>      
> It should not be empty but an error message "Never send initialize to super on the class side!"
>
>    

I  wanted to create a universal dictionary  in my class and populate it
with default values and didn't want to miss initializing anything higher
in the hierarchy. I can see what this isn't the best thing to do since
presumably all the rest of the hierarchy's classes have already been
initialized anyway. What is the proper (or at least better) pattern for
what I want to do?

Lawson

Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Bert Freudenberg

On 12.08.2010, at 23:42, Lawson English wrote:

> On 8/12/10 12:20 PM, Bert Freudenberg wrote:
>> On 12.08.2010, at 20:48, Andreas Raab wrote:
>>
>>  
>>> On 8/12/2010 10:44 AM, Jecel Assumpcao Jr. wrote:
>>>    
>>>> So the file in had actually worked just fine, but at this point deleted
>>>> all the instance methods that had just been created. This might cause
>>>> problems for others, but I didn't call it a "bug" since each part is
>>>> correct in itself. Perhaps there should be a warning for 1? I imagine
>>>> that would be annoying and even scary when loading stuff out of order.
>>>>      
>>> What do you think about implementing ProtoObject class>>initialize as an empty stub? This would act as a backstop for situations like these.
>>>    
>> It should not be empty but an error message "Never send initialize to super on the class side!"
>>
>>  
>
> I  wanted to create a universal dictionary  in my class and populate it with default values and didn't want to miss initializing anything higher in the hierarchy. I can see what this isn't the best thing to do since presumably all the rest of the hierarchy's classes have already been initialized anyway. What is the proper (or at least better) pattern for what I want to do?

Just initialize the class you want. Do not send to super. Class initializers are executed manually only anyway (e.g. when you freshly load a class into a system).

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Bert Freudenberg
In reply to this post by Randal L. Schwartz

On 12.08.2010, at 21:41, Jecel Assumpcao Jr. wrote:

> Randal L. Schwartz wrote on Date: Thu, 12 Aug 2010 12:46:52 -0700
>> Jecel> 1) the class was defined as a subclass of something that was not in the
>> Jecel> image, so the system was silently making it a subclass of ProtoObject
>> Jecel> instead (though the browser said it was a subclass of Object - very
>> Jecel> odd). Didn't we have a warning for this situation?
>>
>> I can't imagine any case where
>>
>>  Foo subclass: #Bar [...]
>>
>> should *succeed* if Foo doesn't exist.  Can you explain why this isn't fatal?
>
> Indeed, I would expect the compiler to refuse to accept this code since
> it can't know what to do with "Foo". But I am guessing that somehow that
> is being silently converted into a translation to nil instead.

Not "somehow". There is no special compiler magic for this. It's an unknown global, so simply becomes an entry in Undeclared with a value of nil.

- Bert -

> UndefinedObject does have a
> #subclass:instanceVariableNames:classVariableNames:poolDictionaries:cate
> gory: instance method to deal with legacy code that has the hack "nil
> subclass: #Bar ..." to implement proxies and stuff - it just now
> redirects it to the proper ProtoObject class.
>
> -- Jecel
>
>



Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Trygve
In reply to this post by Bert Freudenberg
We had two methods for initializing on the class side in OOram: initialize and tmInitialize.
  • initialize initialized the class as a stand-alone entity. It only used the class library and was independent of any of the application classes. It could be called at any time during filein and must be called for all classes before tmInitialize.
  • tmInitialize initialized the class as a member of an application. It assumed that all application classes had been filed in. This meant that a class  variable could be an instance of an application class.
All class initialization methods were modified so that hey could be repeated at any time.. A service method initialized all classes; it was typically called before saving an image.

Just my two cents worth
--Trygve

On 2010.08.12 21:20, Bert Freudenberg wrote:
On 12.08.2010, at 20:48, Andreas Raab wrote:

  
On 8/12/2010 10:44 AM, Jecel Assumpcao Jr. wrote:
    
So the file in had actually worked just fine, but at this point deleted
all the instance methods that had just been created. This might cause
problems for others, but I didn't call it a "bug" since each part is
correct in itself. Perhaps there should be a warning for 1? I imagine
that would be annoying and even scary when loading stuff out of order.
      
What do you think about implementing ProtoObject class>>initialize as an empty stub? This would act as a backstop for situations like these.
    

It should not be empty but an error message "Never send initialize to super on the class side!"

- Bert -



  

--
--

Trygve Reenskaug       mailto: [hidden email]

Morgedalsvn. 5A         http://heim.ifi.uio.no/~trygver

N-0378 Oslo               Tel: (+47) 22 49 57 27

Norway



Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Eliot Miranda-2
In reply to this post by Bert Freudenberg


On Fri, Aug 13, 2010 at 1:01 AM, Bert Freudenberg <[hidden email]> wrote:

On 12.08.2010, at 21:41, Jecel Assumpcao Jr. wrote:

> Randal L. Schwartz wrote on Date: Thu, 12 Aug 2010 12:46:52 -0700
>> Jecel> 1) the class was defined as a subclass of something that was not in the
>> Jecel> image, so the system was silently making it a subclass of ProtoObject
>> Jecel> instead (though the browser said it was a subclass of Object - very
>> Jecel> odd). Didn't we have a warning for this situation?
>>
>> I can't imagine any case where
>>
>>  Foo subclass: #Bar [...]
>>
>> should *succeed* if Foo doesn't exist.  Can you explain why this isn't fatal?
>
> Indeed, I would expect the compiler to refuse to accept this code since
> it can't know what to do with "Foo". But I am guessing that somehow that
> is being silently converted into a translation to nil instead.

Not "somehow". There is no special compiler magic for this. It's an unknown global, so simply becomes an entry in Undeclared with a value of nil.

I'm assuming that the problem is that when the global is defined there is no magic that arranges to recompile the subclass and it remains a subclass of nil^H^H^HProtoObject, right?

I was going to reply earlier in the thread that one jsutification is circular package dependencies.  e.g. package Foo defines classes A & C, package Bar defines class B.  Class hierarchy is A subclass: #B, B subclass: #C.  Can't load Foo or Bar without a hack.  But unless the system records ProtoObject subclasses that have been parented there-form for the purposes of deferring resolution of Undeclared references and reevaluates their correct definitions when previously undeclared classes are declared this isn't much use.  In my Parcel loader the system does do this, but it hides classes subclassed from "absent" classes until those classes become present.  The Squeak approach is simpler (and has much less fall-out on tools etc), but it would be nice if orphaned classes could be redefined as parent classes arrive.

best
Eliot
 

- Bert -

> UndefinedObject does have a
> #subclass:instanceVariableNames:classVariableNames:poolDictionaries:cate
> gory: instance method to deal with legacy code that has the hack "nil
> subclass: #Bar ..." to implement proxies and stuff - it just now
> redirects it to the proper ProtoObject class.
>
> -- Jecel
>
>






Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Casey Ransberger-2
I think I've hit this before. Repro is, filein in the wrong order, wind up with things erroneously inheriting from ProtoObject? It's totally evil, and I thought it was expected behavior (haven't seen it work any other way that I can recall.)

On Aug 13, 2010, at 12:14 PM, Eliot Miranda <[hidden email]> wrote:



On Fri, Aug 13, 2010 at 1:01 AM, Bert Freudenberg <[hidden email]> wrote:

On 12.08.2010, at 21:41, Jecel Assumpcao Jr. wrote:

> Randal L. Schwartz wrote on Date: Thu, 12 Aug 2010 12:46:52 -0700
>> Jecel> 1) the class was defined as a subclass of something that was not in the
>> Jecel> image, so the system was silently making it a subclass of ProtoObject
>> Jecel> instead (though the browser said it was a subclass of Object - very
>> Jecel> odd). Didn't we have a warning for this situation?
>>
>> I can't imagine any case where
>>
>>  Foo subclass: #Bar [...]
>>
>> should *succeed* if Foo doesn't exist.  Can you explain why this isn't fatal?
>
> Indeed, I would expect the compiler to refuse to accept this code since
> it can't know what to do with "Foo". But I am guessing that somehow that
> is being silently converted into a translation to nil instead.

Not "somehow". There is no special compiler magic for this. It's an unknown global, so simply becomes an entry in Undeclared with a value of nil.

I'm assuming that the problem is that when the global is defined there is no magic that arranges to recompile the subclass and it remains a subclass of nil^H^H^HProtoObject, right?

I was going to reply earlier in the thread that one jsutification is circular package dependencies.  e.g. package Foo defines classes A & C, package Bar defines class B.  Class hierarchy is A subclass: #B, B subclass: #C.  Can't load Foo or Bar without a hack.  But unless the system records ProtoObject subclasses that have been parented there-form for the purposes of deferring resolution of Undeclared references and reevaluates their correct definitions when previously undeclared classes are declared this isn't much use.  In my Parcel loader the system does do this, but it hides classes subclassed from "absent" classes until those classes become present.  The Squeak approach is simpler (and has much less fall-out on tools etc), but it would be nice if orphaned classes could be redefined as parent classes arrive.

best
Eliot
 

- Bert -

> UndefinedObject does have a
> #subclass:instanceVariableNames:classVariableNames:poolDictionaries:cate
> gory: instance method to deal with legacy code that has the hack "nil
> subclass: #Bar ..." to implement proxies and stuff - it just now
> redirects it to the proper ProtoObject class.
>
> -- Jecel
>
>







Reply | Threaded
Open this post in threaded view
|

Re: problem with filein

Eliot Miranda-2


On Fri, Aug 13, 2010 at 12:58 PM, Casey Ransberger <[hidden email]> wrote:
I think I've hit this before. Repro is, filein in the wrong order, wind up with things erroneously inheriting from ProtoObject? It's totally evil, and I thought it was expected behavior (haven't seen it work any other way that I can recall.)

One work-around is to use the ChangeList to select al class definitions and simply evaluate them N times.  I think N times is guaranteed to resolve N class definitions.  e.g. consider A <- B <- C <- D, A a superclass of B, D inheriting from C, B & A etc, occurring in the file as D, C, B, A.  The first evaluation leaves A correct and B, C & D inheriting from ProtoObject.  The second evaluation picks up C as inheriting from D, and so on.

So e.g. with my tweaks to the ChangeList in trunk you can file-in, open the ChangeList, remove unchanged definitions, reevaluate, remove unchanged definitions, rinse and repeat until  no defs are left.

best
Eliot



On Aug 13, 2010, at 12:14 PM, Eliot Miranda <[hidden email]> wrote:



On Fri, Aug 13, 2010 at 1:01 AM, Bert Freudenberg <[hidden email][hidden email]> wrote:

On 12.08.2010, at 21:41, Jecel Assumpcao Jr. wrote:

> Randal L. Schwartz wrote on Date: Thu, 12 Aug 2010 12:46:52 -0700
>> Jecel> 1) the class was defined as a subclass of something that was not in the
>> Jecel> image, so the system was silently making it a subclass of ProtoObject
>> Jecel> instead (though the browser said it was a subclass of Object - very
>> Jecel> odd). Didn't we have a warning for this situation?
>>
>> I can't imagine any case where
>>
>>  Foo subclass: #Bar [...]
>>
>> should *succeed* if Foo doesn't exist.  Can you explain why this isn't fatal?
>
> Indeed, I would expect the compiler to refuse to accept this code since
> it can't know what to do with "Foo". But I am guessing that somehow that
> is being silently converted into a translation to nil instead.

Not "somehow". There is no special compiler magic for this. It's an unknown global, so simply becomes an entry in Undeclared with a value of nil.

I'm assuming that the problem is that when the global is defined there is no magic that arranges to recompile the subclass and it remains a subclass of nil^H^H^HProtoObject, right?

I was going to reply earlier in the thread that one jsutification is circular package dependencies.  e.g. package Foo defines classes A & C, package Bar defines class B.  Class hierarchy is A subclass: #B, B subclass: #C.  Can't load Foo or Bar without a hack.  But unless the system records ProtoObject subclasses that have been parented there-form for the purposes of deferring resolution of Undeclared references and reevaluates their correct definitions when previously undeclared classes are declared this isn't much use.  In my Parcel loader the system does do this, but it hides classes subclassed from "absent" classes until those classes become present.  The Squeak approach is simpler (and has much less fall-out on tools etc), but it would be nice if orphaned classes could be redefined as parent classes arrive.

best
Eliot
 

- Bert -

> UndefinedObject does have a
> #subclass:instanceVariableNames:classVariableNames:poolDictionaries:cate
> gory: instance method to deal with legacy code that has the hack "nil
> subclass: #Bar ..." to implement proxies and stuff - it just now
> redirects it to the proper ProtoObject class.
>
> -- Jecel
>
>