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

> 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
> 
> 
> On 2010-12-16 15:10 Derrell Lipman wrote:
> > On Thu, Dec 16, 2010 at 07:12, Peter Schneider 
> > <[email protected]>wrote:
> > 
> >>
> >> 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 ;)
> >>
> > 
> > I don't recall this prior conversation, but I think I disagree with one of
> > Ralf's givens:
> > 
> > 
> >>> 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.
> >>
> > 
> > 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.
> > 
> > 
> >>
> >> 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);
> >>  },
> >>
> > 
> > Hmmm... You can either put this.setContextMenuHandler() into the defer
> > section (probably your best option), or try this:
> > 
> > qx.Class.define("app.ContextTable",
> > {
> >  extend  : qx.ui.table.Table,
> >  include : qx.ui.table.MTableContextMenu,
> > 
> >  construct : function (tableModel)
> >  {
> >    this.base(arguments, tableModel);
> > 
> >    // Set a timer to add our context menu handler after MTableContextMenu
> > has been mixed in
> >    qx.util.TimerManager.getInstance().start(
> >      function(userData, timerId)
> >      {
> >        this.setContextMenuHandler(0, this.__handler, this);
> >      },
> >      0, this, null, 1);
> >  },
> 
> 
> 
> ------------------------------


------------------------------------------------------------------------------
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

Reply via email to