On Fri, Apr 8, 2011 at 20:32, hgc2002 <[email protected]> wrote:

> I've done a trace on my application because some private variables were
> getting null from no-where after the setting routine had run perfectly.
>
> The truth was that the private variable was part of a Mixin, and the
> setting/getting routines too. But also the constructor, that was the only
> place where the variable was defined as this.__var = null.
>
> Why the Mixim constructor is called at the end of the object construction?
> When I say "object construction" I'm referring to the constructor of a
> simple Qooxdoo derived object that calls some Mixin routines while its
> constructor routine.
>
> Let me try to draw it:
>
> new Object1-->constructor of Object1 runs-->it runs routines from Mixim1 in
> the Object1 constructor-->end of Object1 constructor-->Constructor of
> Mixin1
> runs!!!
>
> It should be:
>
> new Object1 --> constructor of Object1 runs --> constructor of Mixim1
> runs--> Object1's constructor continues-->Object1's constructor run
> routines
> from Mixim1-->end of Object1's constructor-->done
>

Here's a previous discussion of this topic. I explained why your suggested
order doesn't work in some cases, and someone else actually tried to reverse
it but found all sorts of problems. There are valid arguments to do it both
ways.

Derrell



Forwarded conversation
Subject: [qooxdoo-devel] Mixin constructor should be called before 'normal'
constructor
------------------------

From: *Peter Schneider* <[email protected]>
Date: Thu, Dec 16, 2010 at 07:12
To: qooxdoo Development <[email protected]>


Hi there,

I strongly feel that the current order of constructor calls for mixins is
wrong.
I didn't want to necropost a thread by Ralf Nieuwenhuijsen[1] that is about
2.5
years old...but it basically explains the reason of this wrong behavior an I
therefore took the liberty and "stole" his description from that thread ;)

Problem/Issue:
==============
> [...]
> The mixin constructor is called _after_ the normal constructor rather than
> before. This is the wrong default.
>
> Why? Because the mixin can make no assumptions about the class it's mixed
> in.. so it won't be calling or setting properties other than its own.
>
> But the class using the mixin knows its using the mixin. It wants to use
the
> mixin in the contructor, but it can't.
> [...]


Example:
========
It is not possible to do this:

<code>
qx.Class.define("app.ContextTable",
{
 extend  : qx.ui.table.Table,
 include : qx.ui.table.MTableContextMenu,

 construct : function (tableModel)
 {
   this.base(arguments, tableModel);
   // This *fails*, 'cause the mixins constructor was not yet called!
   this.setContextMenuHandler(0, this.__handler, this);
 },

 members :
 {
   __handler: function (col, row, table, dataModel, contextMenu) {
     return false; // implementation stripped for clarity
   }
 }
});
</code>


I think I will open a bug for this.

In the mean time, does anybody have an idea how to work around this issue
with
the current implementation?
My current version (which I don't really like) looks like this:

<code>
qx.Class.define("app.ContextTable",
{
 extend  : qx.ui.table.Table,
 include : qx.ui.table.MTableContextMenu,

 construct : function (tableModel) {
   this.base(arguments, tableModel);
 },

 members :
 {
   /* This method _has_to_be_called_ after instantiating this Table :( */
   initContextMenu : function ()
   {
     this.setContextMenuHandler(0, this.__handler, this);
     return this; // for chaining support
   },

   __handler: function (col, row, table, dataModel, contextMenu) {
     return false; // implementation stripped for clarity
   }
 }
});

// ... somewhere else:
   var tableModel = new qx.ui.table.model.Simple;
   // ...
   var table = new app.ContextTable(tableModel).initContextMenu();
// ...
</code>

Thanks in advance for any hints,
 Peter


[1] http://old.nabble.com/Problems-with-Mixins-td16806052.html#a16806052

------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
qooxdoo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

----------
From: *Gabriel Munteanu* <[email protected]>
Date: Thu, Dec 16, 2010 at 08:35
To: qooxdoo Development <[email protected]>


Hi,
You can have a look at defer, maybe that will help you in some way:
http://manual.qooxdoo.org/1.3/pages/core/oo_feature_summary.html
something like this:
defer: function(statics,members,properties){
       members.setContextMenuHandler(0,members.__handler);
   }
not tested.

cheers,
Gabi
________________________________________
From: Peter Schneider [[email protected]]
Sent: Thursday, December 16, 2010 2:12 PM
To: qooxdoo Development
Subject: [qooxdoo-devel] Mixin constructor should be called before 'normal'
    constructor

----------
From: *Derrell Lipman* <[email protected]>
Date: Thu, Dec 16, 2010 at 08:42
To: [email protected], qooxdoo Development <
[email protected]>


I don't recall this prior conversation, but I think I disagree with one of
Ralf's givens:
That is true only if the mixin is included with the "include:" member of the
class description. A mixin can also be included into a class with
qx.Class.include(), in which case the class does not know that the mixin is
available. The current order of constructor calls is appropriate for this
usage. I can see a valid argument for changing the constructor order when
the mixin is included directly into a class, and leaving it as it is when
qx.Class.include() is used... but then there's an inconsistency which may
disallow the mixin from being used both ways. A mixin must be able to be
used both ways.
Hmmm... You can either put this.setContextMenuHandler() into the defer
section (probably your best option), or try this:
   // Set a timer to add our context menu handler after MTableContextMenu
has been mixed in
   qx.util.TimerManager.getInstance().start(
     function(userData, timerId)
     0, this, null, 1);
 },


----------
From: *Peter Schneider* <[email protected]>
Date: Thu, Dec 16, 2010 at 09:08
To: qooxdoo Development <[email protected]>
Cc: Gabriel Munteanu <[email protected]>


Hi Gabriel,

that "defer" approach came to my mind, too. But this will also fail,...
but different ;)

The defer "method" is called on the _class_, not on an _instance_ of it.
So this fails earlier (at start-up[2] of the application) instead of failing
when the first instance is created ;)

Nevertheless, thank you.

Cheers,
 Peter


[2] Where all the qx.Class.define("app.ContextTable",{...}); calls are
   executed.

----------
From: *Derrell Lipman* <[email protected]>
Date: Thu, Dec 16, 2010 at 09:15
To: [email protected], qooxdoo Development <
[email protected]>
Cc: Gabriel Munteanu <[email protected]>


Doh! I fell into that mistake too, but I'm going to attribute it to
responding pre-caffeine. :-) My other suggestion should work for you I
think, though.

Derrell


----------
From: *Peter Schneider* <[email protected]>
Date: Thu, Dec 16, 2010 at 09:18
To: qooxdoo Development <[email protected]>
Cc: Derrell Lipman <[email protected]>


Hello Derrell,

thanks for the reply, but I think I don't get it. Probably I misunderstand
your
arguments.

You say that qx.Class.include() can be used as well. I agree, but what would
be the difference to the "direct" include?

When I do:
<code>
 qx.Class.include("app.ContextTable", "qx.ui.table.MTableContextMenu");
 var table = new app.ContextTable(tableModel);
</code>
wouldn't this be the same than using the "include:" member in the class
definition of "app.ContextTable"? The constructor is called whenever I use
the
"new" operator, right?

In case I misunderstand you completely, please be patient and try to push me
into the correct direction ;)

Cheers,
 Peter

----------
From: *Derrell Lipman* <[email protected]>
Date: Thu, Dec 16, 2010 at 09:25
To: [email protected], qooxdoo Development <
[email protected]>


You had copied, from Ralf's post, "But the class using the mixin knows its
using the mixin." That's not the case when qx.Class.include() is used to
attach a mixin to a class. The class may have no knowledge at all that the
mixin is attached to it. Rather, users of instances of that class know that
the mixin features are available.

That's why the class can't assume that the mixin is available in this case.
In the case with the include member of the class definition it could make
that assumption, but then you'd have two different orders of operation which
couldn't be counted on.

Does that make more sense?

Derrell


----------
From: *Peter Schneider* <[email protected]>
Date: Thu, Dec 16, 2010 at 09:55
To: qooxdoo Development <[email protected]>
Cc: Derrell Lipman <[email protected]>


Hello Derrell

Yes, after your explanation it makes your point more  clear ;) Thank you.

But isn't the order of the constructor-calls independent of this?


I thought about the qx.Class.include() approach as well but I decided
against
this for the following (personal) reasons:

If one uses the qx.Class.include() approach, I assume that the calling of
the
Mixins methods will also be in the area of the instantiation
<pre class='javascript'>
 // ...
 initGUI : function () {
   // ...
   table.setContextMenuHandler(0, this.__contextMenuHandler, this);
   // ...
 },
 __contextMenuHandler : function (/*...*/) {
   // ...
 }
 // ...
</pre>

With the "__contextMenuHandler" being a method of the calling class, which
is
something I would not expect.

And the app.ContextTable class definition would shrink into something like:

<pre class='javascript'>
 });
</pre>


Still, I don't think the constructor-call order is the best as it currently
is.
I will just try to swap the constructor-call order of my local framework
copy
(qx.Class.__wrapConstructor lines 1618 - 1638) and see what happens...
Maybe I get a feeling if this does more harm than help :-D

Stay tuned for any results...

 Peter

----------
From: *Peter Schneider* <[email protected]>
Date: Thu, Dec 16, 2010 at 10:15
To: [email protected], qooxdoo Development <
[email protected]>
Cc: Derrell Lipman <[email protected]>


On 2010-12-16 16:08 Peter Schneider wrote:
> [...]
> [...]

As expected it totally breaks my application :-D

(qx.ui.core.MResizable e.g. expects to be included by a class that provides
a
 getContainerElement() method...)

So just in case anyone thinks this _could_ work: It doesn't ! ;)


Does anyone with Java experience have information about how this is done in
Java? I think the concept of Mixins was borrowed from Java, wasn't it?

Anyway, I stick to my 1st approach (the one with the initContextMenu()
method
that has to be called after instantiation)

I don't think an enhancement/bug should be made for this until more
developers
feel *really* bad about this.

Thanks for the discussion so far,
 Peter

----------
From: **<[email protected]>
Date: Tue, Dec 21, 2010 at 07:21
To: [email protected]
Cc: [email protected]


Hi.

Just my opinion: mixins are sort of like partial base classes. IMO it's only
reasonable that their constructor is called before the constructor of the
containing/inheriting class. In case you need a mixin that has to rely on
features of the including class, you can use template method in the base
class'es constructor. But in such a case a mixin is IMO improperly used.

Semantically, mixins are there to add generic functionality to various
classes, not to change/augment classes in ways of which the classes are not
aware - this is what AOP is for, not mixins. Therefore, mixins shouldn't
rely on the class including them, whereas the including class can
legitimately rely on implementation of the included mixins. For this to
always work, mixin parts of an object should be initialized before the part
corresponding to the actual class.

br,

flj
> When I do:
> <code>
>   Peter
>
>
> ------------------------------

----------
From: **<[email protected]>
Date: Tue, Dec 21, 2010 at 07:31
To: [email protected]
Cc: [email protected]


Hi.
I may be wrong, but in the more than ten years or so of me using Java I
never saw anything related to mixins in Java.

.Net/C# has introduced the concept of partial classes, but these aren't like
qooxdoo's mixins, in that what actually happens is just that the code of all
partial classes defining one complete class is put together at compile time
- i.e. no inclusion of a partial class into several different complete
classes.

Here's a nice reading about mixins and their history:
http://c2.com/cgi/wiki?MixIn.

br,

flj

----------
From: *Jean-Baptiste BRIAUD -- Novlog* <[email protected]>
Date: Tue, Dec 21, 2010 at 08:07
To: qooxdoo Development <[email protected]>


No mixins in Java unfortunately.
I think I saw this in Lisp.

Partial class is not the same as mixins since you can't share parts.

----------
From: *Peter Schneider* <[email protected]>
Date: Tue, Dec 21, 2010 at 08:37
To: qooxdoo Development <[email protected]>
Cc: [email protected]


I agree (100%, no wonder ;) )

Nevertheless I don't think this "wrong" behavior can be fixed easily in the
qooxdoo framework. Some (many) parts might rely on this.
Even if the framework occurrences can be found and fixed there might be some
applications out there that do the same :(

>From my point of view the first thing that has to be done is to document
clearly the constructor-call sequence (base-class,class,mixin(s)).
I think the sequence in which constructors from multiple mixins are called
will depend on their appearance in the "include : []" array.

If the sequence can be swapped easily (framework-fix), I would welcome this
very much!
(A migration-script could drop a note on mixin-usage for application
developers on this)

/Peter


>
> br,
>
> flj
>
>[...]
------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
qooxdoo-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/qooxdoo-devel

Reply via email to