*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 <stephane.duca...@inria.fr>

>
> On Dec 3, 2013, at 11:20 AM, Clément Bera <bera.clem...@gmail.com> 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 <stephane.duca...@inria.fr>
>
>> > 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