thanks for your analysis I will have a look at it.

I was thinking to check if I should redefine UndefinedObject>>subclass:
to raise an error 

Stef


On Dec 3, 2013, at 3:17 PM, Clément Bera <[email protected]> wrote:

> do you know if the OCUndeclaredVariable is raised for unknown superclass?
> 
> this code:
> 
> AnUnknownClass subclass: #Adaptor1Example
>         instanceVariableNames: 'customers accountID address name phoneNumber'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'Examples-Cookbook'
> 
> is run as a Do It. In Do It, unknown variables (as here AnUnknownClass) raise 
> an OCUndeclaredVariableWarning.
> For example, running:
> 
> AnUnknownClass subclass: #Adaptor1Example
>         instanceVariableNames: 'customers accountID address name phoneNumber'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'Examples-Cookbook'
> 
> executes the default action for OCUndeclaredVariableWarning, which is opening 
> a pop-up titled: "Unknown variable ...". Here the error is raised at 
> compilation time, therefore it would have no effect to wrap this with a 
> #on:do: 
> 
> [ AnUnknownClass subclass: #Adaptor1Example
>         instanceVariableNames: 'customers accountID address name phoneNumber'
>         classVariableNames: ''
>         poolDictionaries: ''
>         category: 'Examples-Cookbook' ] on: OCSemanticWarning do: [ ]
> 
> ==> same problem.
> 
> Now if you do: 
> 
> [ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example
>         instanceVariableNames: ''customers accountID address name 
> phoneNumber''
>         classVariableNames: ''''
>         poolDictionaries: ''''
>         category: ''Examples-Cookbook''' ] on: OCSemanticWarning do: [ :e | e 
> halt ]
> 
> Here we catch the error, and you can handle it. 
> Now it is not easily possible to resume the error, because you want a global 
> instead and Opal expects a temp (there are way to resume but with very deep 
> stack manipulation that I do not want to show to young pharoers present on 
> this mailing list). So the best is to retry it. One solution is therefore:
> 
> [ OpalCompiler new evaluate: 'AnUnknownClass subclass: #Adaptor1Example
>         instanceVariableNames: ''customers accountID address phoneNumber''
>         classVariableNames: ''''
>         poolDictionaries: ''''
>         category: ''Examples-Cookbook''' ] 
> on: OCSemanticWarning do: [ :e | 
>       Smalltalk at: e node name put: StubRootClass.
>       e retry ] 
> 
> with e node name answering #AnUnknownClass here.
> Now you need to make sure that the exception block is executed for the case 
> of a missing superclass and not something else or you will end up creating 
> loads of globals.
> 
> The exception block should be something similar to:
> 
>  [ :e | 
>         e node name first isUppercase and: [ "some condition" ] ifTrue: [
>               Smalltalk at: e node name put: StubRootClass.
>               ^ e retry ].
>         e pass ] 
> 
> How to undefined and OCUndeclaredVariableWarning relate?
> 
> In your case, while loading from Monticello the code is compiled and 
> evaluated in non interactive mode. Therefore it cannot trigger the default 
> action of OCUndeclaredVariableWarning which is a UI event. So it sets by 
> default the unknown global to:
> 
> Undeclared at: varName asSymbol put: nil.
> OCUndeclaredVariable new name: varName asSymbol
> 
> in: OCUndeclaredVariableWarning >>defaultAction
> 
> which then later triggers the code in UndefinedObject.
> 
> 
> 
> 2013/12/3 Stéphane Ducasse <[email protected]>
> 
> On Dec 3, 2013, at 11:20 AM, Clément Bera <[email protected]> wrote:
> 
>> Then for your project replace ProtoObject by StubRootClass in 
>> UndefinedObject>>subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:
>>  it will work.
> 
> yes but this is ugly because I do not want override.
> So I will introduce an exception so that we can do that in a clean way.
> 
> 
>> An alternative is to catch OCSemanticWarning or its subclass 
>> OCUndeclaredVariableWarning while loading the new classes and execute 
>> another code instead of the default action in the exception handling block
> 
> 
> do you know if the OCUndeclaredVariable is raised for unknown superclass?
> How to undefined and OCUndeclaredVariableWarning relate?
> 
> Stef
>> 
>> 
>> 2013/12/3 Stéphane Ducasse <[email protected]>
>> > Well if the class does not exists it calls the method on UndefinedObject 
>> > (UndeclaredBinding). And you have:
>> 
>> I will check and see if I can set up a hook because having classes 
>> subclasses of protoobject is not a good idea
>> when loading broken code.
>> 
>> > UndefinedObject>>subclass: nameOfClass
>> >       instanceVariableNames: instVarNames
>> >       classVariableNames: classVarNames
>> >       poolDictionaries: poolDictnames
>> >       category: category
>> >       "Calling this method is now considered an accident.  If you really 
>> > want to create a class with a nil superclass, then create the class and 
>> > then set the superclass using #superclass:"
>> >       self traceCr: ('Attempt to create ', nameOfClass, ' as a subclass of 
>> > nil.  Possibly a class is being loaded before its superclass.').
>> >       ^ProtoObject
>> >               subclass: nameOfClass
>> >               instanceVariableNames: instVarNames
>> >               classVariableNames: classVarNames
>> >               poolDictionaries: poolDictnames
>> >               category: category
>> >
>> > The best is to set manually the superclass after with #superclass:
>> 
>> No because I have no idea what are the classes whose superclasses are not in 
>> the image.
>> With a proper hook I could just say
>>         if the superclass is unknow please use the "StubRootClass" of my 
>> framework.
>>         else let the system handles it.
>> 
>> Stef
>> 
> 
> 

Reply via email to