[Laszlo-dev] init vs oninit vs super.init

Elliot Winard enw at laszlosystems.com
Wed Aug 8 11:38:44 PDT 2007


Also, classes that overwrite init and don't call super.init() 
immediately make it difficult to figure out what's going on if a 
developer is looking at the superclass' init method and wondering why 
things aren't init'ed properly in the subclass that they're instantiating.

i.e.
<class name="superclass">
    <method name="init">
        super.init();
        // do something here
    </method>
</class>

<class name="subclass" extends="superclass">
    <method name="init">
        // don't call super.init() for some reason that
        // makes good sense here
    </method>
</class>

<subclass>
    <handler name="oninit">
        // developer is confused here because
        // they read the superclass init and expected
        // it to be executed before code goes here.
    </handler>
</subclass>

-e

P T Withington wrote:
> And since I wrote that, I have to agree with Sarah.  Sorry Ben!
>
> You are correct that a general principle of OO design is that you have 
> to understand the method you are overriding _and_ you should always 
> call the super method first, unless you really know what you are 
> doing.  But plain handlers in classes have the limitation that they 
> create un-overridable behavior which limits extensibility.
>
> If you read the link Sarah sent and don't understand the reasoning, 
> please let me know so I can clarify.
>
> ---
> Le iPhone, c'est moi.
>
> On Aug 7, 2007, at 4:12 PM, Sarah Allen <sallen at laszlosystems.com> wrote:
>
>> Generally, we (the Laszlo applications team) don't use events in 
>> classes (see 
>> http://wiki.openlaszlo.org/Best_practices#Handle_events_with_methods_in_classes) 
>>
>> For init this is particularly important, since if you are defining a 
>> class, you would want an init code to run before an oninit of an 
>> instance of that class.  Therefore, it is wise to override the init 
>> method rather than defining an event.
>>
>> Sarah
>>
>> On Tue, Aug 7, 2007 at 12:43 PM, Benjamin Shine wrote:
>>
>>> If I were Tucker, I would say, "You should never override init, 
>>> because if you forget to call super.init(), things are deeply hosed."
>>>
>>> (Tucker's offline for the day so we'll have to wait till tomorrow to 
>>> have him in this discussion.)
>>>
>>> On Aug 7, 2007, at 12:30 PM, Bret Simister wrote:
>>>
>>>> This is about  a choice of design patterns. When extending a class 
>>>> that needs to have new functionality during its initialization,   
>>>> but the subclass also needs to execute the init functionality of  
>>>> its super class, which of the methods below is the  preferred  
>>>> design pattern?
>>>>
>>>> <method name="init" >
>>>>    super.init()
>>>>    ...
>>>> </method>
>>>>
>>>> or
>>>>
>>>> <handler name="oninit" >
>>>>        ...
>>>> </handler>
>>>>
>>>> and rely on the fact that when using the handler, the super.init() 
>>>> of the class is effectively being called because it has not been 
>>>> overridden.
>>>>
>>>> Even if the functionality is identical in both cases, I prefer the 
>>>> explicit design pattern of <method name=" ..." > over the implicit 
>>>> design pattern of <handler name="oninit" >
>>>>
>>>>
>>>> my two cents,
>>>> Bret
>>>>
>>>>
>>>> On Aug 7, 2007, at 12:08 PM, Elliot Winard wrote:
>>>>
>>>>> Hrm.  Actually, subclass init method gets called.  Superclass init 
>>>>> method doesn't get called unless the subclass calls 
>>>>> superclass.init ().
>>>>>
>>>>> The below example is a bit misleading because brusselssprouts  
>>>>> calls super.init() before Debug.outputting.
>>>>> -e
>>>>>
>>>>>
>>>>> ---=---===-------
>>>>> Elliot Winard
>>>>> Sr. Software Engineer
>>>>> Webtop Team
>>>>> ---=---===-------
>>>>>
>>>>>
>>>>> On Tue, Aug 7, 2007 at  2:45 PM, Benjamin Shine wrote:
>>>>>
>>>>>> Bret and I were going through a code change and wanted a 
>>>>>> clarification on what order things were expected to happen:
>>>>>>
>>>>>> <canvas>
>>>>>> <class name="cabbage">
>>>>>>    <method name="init">
>>>>>>        // called FIRST
>>>>>>        Debug.write("cabbage.init (method name=init) on %w", this);
>>>>>>        this.setAttribute("deliciousness", 0.35);
>>>>>>    </method>
>>>>>>    <handler name="oninit">
>>>>>>        // called SECOND
>>>>>>        Debug.write("cabbage.oninit (handler name=oninit) on %w", 
>>>>>> this);
>>>>>>    </handler>
>>>>>> </class>
>>>>>>
>>>>>> <class name="brusselssprout" extends="cabbage">
>>>>>>    <method name="init">
>>>>>>        super.init(); // calls method name="init" on cabbage
>>>>>>        Debug.write("brusselssprout.oninit method on %w,  
>>>>>> deliciousness is %f", this, this.deliciousness);
>>>>>>    </method>
>>>>>>    <handler name="oninit">
>>>>>>        // called *after* cabbage's oninit handler
>>>>>>        Debug.write("brusselssprout.oninit handler on %w, 
>>>>>> deliciousness is %f", this, this.deliciousness);
>>>>>>    </handler>
>>>>>> </class>
>>>>>>
>>>>>> <cabbage id="cabby" />
>>>>>> <brusselssprout id="sprouty" />\
>>>>>> </canvas>
>>>>>>
>>>>>> This produces the following output:
>>>>>> cabbage.init (method name=init) on #cabby
>>>>>> cabbage.oninit (handler name=oninit) on #cabby
>>>>>> cabbage.init (method name=init) on #sprouty
>>>>>> brusselssprout.oninit method on #sprouty,  deliciousness is 0.350000
>>>>>> cabbage.oninit (handler name=oninit) on #sprouty
>>>>>> brusselssprout.oninit handler on #sprouty, deliciousness is 0.350000
>>>>>>
>>>>>>
>>>>>> ...which is just what I expect: superclass methods called before 
>>>>>> sublcass methods, method name="init" called before oninit handler.
>>>>>>
>>>>>> Is this the guaranteed order of execution?
>>>>>>
>>>>>> -ben
>>>>



More information about the Laszlo-dev mailing list