On 2009-11-24, at 17:01, Rami Ojares / AMG Oy wrote:

> Hi,
> 
> Current documentation has this to say about node's createChildren(carr) 
> argument
> 
> "an array of children where the structure of each child [c] takes the form:
> c.name = a string containing the name of the child -- usually its constructor
> c.args = a dictionary of attributes and values to be passed to the 
> constructor of that child
> c.children = an array of children for the new child"

You are venturing into things that most people don't, since they just use the 
XML language for their applications.

I think the documentation on makeChild is more accurate.  createChildren is 
really just a hook to allow a subclass to change where and when it actually 
makes its children.  makeChild is the interface that actually interprets the 
children specification.  (Don't blame me for the confusing names, I did not 
make them up!)

c.name is still valid, it is used to make a child be of the class that 
implements a particular tag (so you say 'view' to get a <view>, etc.  You can 
use this to make any node that has a tag).

c.class is an optimization, used by the compiler to:

1) Avoid having to look up the name
2) Instantiate 'instance classes'

> None of this seems to be true.
> Instead the children seems to have the structure:
> c.attrs = a dictionary of attributes and values to be passed to the 
> constructor of that child
> c.class = pointer to the class to be instantiated
> 
> When you further inspect the class there is one useful attribute:
> tagname. That seems to have the same function as c.name in the above 
> mentioned documentation.
> 
> Further it seems that in the current trunk if you instantiate a class with a 
> constrained attribute like this
> 
> <view height="${foo.height}"/>
> 
> It's tagname becomes
> "anonymous tagname"

Right.  This is a so-called "instance class".  In order to have a constraint, 
an instance needs some supporting methods.  (You would see the same thing if 
you gave your instance an explicit <method>.)  In order to have methods, the 
compiler has to build a class, and then make just one instance of that class.  
It doesn't define a tag for that class, because it will only ever be made by 
the compiler (or by replication, which works automatically).  The tagname in 
this case, is just for debugging.  If you were to look at the non-debug 
version, you would see the tagname is not emitted.  And of course, the class is 
_not_ entered into `lz` (as are all real class definitions, e.g., lz['view'] => 
the class that implements <view>, so lz[<any tag name>].tagname == <any tag 
name>, but not for 'anonymous' or 'instance' classes.)

> Code:
> 
> <canvas debug="true">
>    <view >
>        <method name="createChildren" args="children"><![CDATA[
>            for(var i=0; i<children.length; i++) {
>                Debug.write(children[i]['class'].tagname);
>            }
>        ]]></method>
>        <view height="${canvas.height}"/>
>        <view/>
>    </view>
> </canvas>
> 
> Produces the output in debug window:
> anonymous view
> view
> 
> Is this how it is supposed to be?

That's how it is supposed to be.  :)

> Or is this an accident caused by the instance specific mixin development?

Although, we did just add this feature to make it easier to debug instance 
mixin's.  Before, we never emitted a tagname for "instance classes".  But we 
decided it would help debugging to give them a tagname that told what tag they 
were derived from.


Reply via email to