Folks,

Sorry, this is probably a better implementation of _lazyeach:
http://pastie.org/258491

wrapAll() converts the lazy-mode list into a wrapped-mode list by
making sure all elements are wrapped and reverting item() and _each()
to the prototype's versions; _lazyeach() just calls wrapAll() and
returns _each().

-- T.J. :-)

On Aug 22, 10:58 pm, "T.J. Crowder" <[EMAIL PROTECTED]> wrote:
> @Ken:
>
> > Of course an argument /against/ lazy wrapping is that we would have to
> > make "this.raw" a private property because you wouldn't know if it
> > contains wrapped or unwrapped elements.
>
> Yeah, that was my primary reason for keeping it separate; originally I
> was thinking integrated as well but I'm a bare metal kind of guy and
> want access to a raw list.  (Can you tell I spent my formative years
> as a C programmer in performance-challenged environments?)  But it
> definitely takes more memory.  For a 1,000 node list, it's 1,000 extra
> references (duh), which best case is 4k and more likely 8-24k; it
> totally depends on how an implementation implements JavaScript's
> sparse arrays.
>
> @All:
>
> I have a kookie idea for you guys.  How 'bout not making this decision
> for the users (except as a default)?  In fact, how 'bout not
> conflating selection and wrapping?  This is totally off the top of my
> head and may look really stupid in the morning, but:
>
> Usage:
>
>     // I want a raw list:
>     var rawList = $$('.foo');
>
>     // I want a wrapped list of wrapped elements, so I wrap it:
>     var wrappedList = $L($$('.foo'));
>
>     // I want a lazily-wrapped list:
>     var lazyList = $L($$('.foo'), "lazy");
>
> Doesn't have to be $L(), whatever, I'm just using that a as
> placeholder for a convenient list wrapper like $W() is for elements.
>
> Concept source excerpts for NodeList:
>
>     initialize:  function(source, style) {
>         style = style || "prewrap";
>         this.length = source.length;
>         if (style == "lazy") {
>             this.source = source;
>             this.wrappers = [];
>             this.item = this._lazyitem;
>             this._each = this._lazyeach;
>         }
>         else /* assume "prewrap" */ {
>             this.wrappers = source.map($W);
>         }
>     },
>
>     size:  function() {
>         return this.length;
>     },
>
>     item:  function(index) {
>         return this.wrappers[index];
>     },
>
>     _lazyitem:  function(index) {
>         return this.wrappers[index] || (this.wrappers[index] =
> $W(this.source[index]));
>     },
>
>     _each: function(iterator) {
>         this.wrappers._each(iterator);
>     }
>
>     _lazyeach:  function(iterator) {
>         var w, s, index, length, value;
>         w = this.wrappers;
>         s = this.source;
>         index = 0;
>         length = s.length;
>         while (index < length) {
>             value = w[index] || (w[index] = $W(s[index]));
>             iterator(value, index++);
>         }
>     }
>
> So there are two concepts in the above:
>
> 1. Why do we need to replace $$() or create $$W()?  Keep $$() as it is
> and offer a way to wrap it.  I think that's kangax's current thought
> anyway.
>
> 2. Other than item() and _each(), what's the difference between a
> prewrapped list and a lazy list?  Provided we ensure that the other
> methods use one of those methods rather than direct access?  Sure, the
> lazy ones (given the source above) end up having their own item() and
> _each() references rather than sharing the prototype's, but hey, a
> whole new class just for this seems a bit over the top.
>
> I have a tendency to go too far on options, and this may be an
> example.  But no one knows better than the ultimate author what better
> suits what they're doing.
>
> But again the above hinges on the question:  Is it really a valid use
> case that people will want a list of lazily-wrapped elements?  I know
> I'll want lists of unwrapped elements (for which I can just keep using
> $$() if it doesn't change), and I'm pretty sure I'll want lists of
> wrapped ones (and so I'll use the nifty new stuff).  But I'm not sure
> I'll want a list where some elements end up wrapped and others don't.
> Maybe if I'm doing some massive kind of big select where it's really
> important to me that we only traverse the DOM once, and then I'll walk
> the array making decisions; that's the only time I can think of and in
> that case I'd just use $$() anyway and wrap things as/when I needed
> the sugar.
>
> -- T.J. :-)
>
> On Aug 22, 9:56 pm, Ken Snyder <[EMAIL PROTECTED]> wrote:
>
> > kangax wrote:
> > > On Aug 22, 11:30 am, "T.J. Crowder" <[EMAIL PROTECTED]> wrote:
>
> > >>> I'm not sure if we should "pre-wrap" elements or do the "lazy init".
> > >>> First approach "hits" the memory consumption, while second - run-time
> > >>> performance. We'll need benchmarks for this.
>
> > >> Yeah.  I know you were initially thinking pre-wrap, and my first
> > >> instinct was lazy-init (of course!), which was part of the point of my
> > >> question.  If I have $$() for my lazy-init needs, I'm less likely to
> > >> weigh in and say $$W() should be lazy-init as well.
>
> > >> That said, lazy-init seems pretty cheap; essentially an extra
> > >> comparison on each item() call.  Thinking out loud:
>
> > >>     initialize:  function(source) {
> > >>         this.source = source;
> > >>         this.wrappers = [];
>
> > > Not sure if having two arrays in each `NodeList` compensates for the
> > > load-time save : ) Definitely an interesting idea, though. I'll think
> > > about it.
> > > ...
> > > --
> > > kangax
>
> > I think you may have already mentioned this, but what about lazy
> > wrapping but altering the raw array? (see below)
>
> > Of course an argument /against/ lazy wrapping is that we would have to
> > make "this.raw" a private property because you wouldn't know if it
> > contains wrapped or unwrapped elements.
>
> > - Ken
>
> > initialize: function(array) {
> >   this.raw = array;
> >   this.length = this.raw.length;}...
>
> > item: function(index) {
> >   if (index < 0 || index >= this.length) return null;
> >   // $W either instantiates a new wrapper, or returns the value
> >   //   if the value is already an instance of Prototype.ElementWrapper
> >   this.raw[index] = $W(this.raw[index]);
> >   return this.raw[index];}...
>
> > _each: function(iterator) {
> >   var index = 0;
> >   while (index < this.length)
> >      iterator(this.item(index), index++);
>
> > }
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Prototype: Core" group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to