[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