Replacing default __iterator__?

Hi,

I'm trying to replace the __iterator__ of an object with a custom
iterator, then iterate over the object in a for..in loop. It seems
that the loop only iterates over the intersection of two sets:
1) the set of properties that would be returned by the default iterator
2) the set of properties returned by the custom iterator

Here's the code I'm testing:
> var obj = {a:1, __iterator__: function() { return (function() { yield "a"; yield 2 })() } }
> for(var i in obj) print(i + "->" + obj[i])
a->1
> obj[2] = 4
4
> for(var i in obj) print(i + "->" + obj[i])
a->1
2->4

Is this behavior expected? I was confused by this and so were the
authors of this test:
http://lxr.mozilla.org/mozilla/source/js/tests/js1_7/iterable/basic-for-each.js
and this comment:
http://developer.mozilla.org/en/docs/Talk:New_in_JavaScript_1.7#Syntax_for_replacing_native_iterators.3F

AFAIK, Python doesn't allow to override __iter__ for dicts, which are
rather similar to JS objects, but it does allow to define a custom
__iter__ method on a class.

Nickolay
0
Nickolay
7/29/2006 11:37:15 PM
mozilla.dev.tech.js-engine 2017 articles. 0 followers. Post Follow

8 Replies
320 Views

Similar Articles

[PageSpeed] 5

Nickolay Ponomarev wrote:
> Is this behavior expected? I was confused by this and so were the
> authors of this test:
> http://lxr.mozilla.org/mozilla/source/js/tests/js1_7/iterable/basic-for-each.js 

I was?  ;-)  I admit to finding __iterator__ initially unintuitive, but I'm not sure how you got that from reading the testcase.

> and this comment:
> http://developer.mozilla.org/en/docs/Talk:New_in_JavaScript_1.7#Syntax_for_replacing_native_iterators.3F 

I figured out the problem; the code there was setting __iterator__ to a Generator, not to a function which returns a Generator.  I expect this will be a fairly common problem for first-time __iterator__ users with JS 1.7.  In general I think people are going to run into initial trouble figuring out the code mechanics needed to support custom iteration using the __iterator__ property.

As for the problem reported here, every time I look at it I think the behavior just might be the correct behavior, but I can never manage to convince myself.  I suspect that code demonstrates a bug, although I'm not sure what the difference is between that code and some of the code in the testcases I wrote for iterators.  In any case, I believe the code in the original MDC question that spawned this, when fixed, will run into the same problem:

http://whereswalden.com/files/mozilla/js-iter-maybe-bug.html

Jeff

-- 
Rediscover the Web!
http://snurl.com/get_firefox

Reclaim Your Inbox!
http://snurl.com/get_thunderbird
0
Jeff
7/30/2006 9:23:09 AM
On 7/30/06, Jeff Walden <jwalden+nmo@mit.edu> wrote:
> Nickolay Ponomarev wrote:
> > Is this behavior expected? I was confused by this and so were the
> > authors of this test:
> > http://lxr.mozilla.org/mozilla/source/js/tests/js1_7/iterable/basic-for-each.js
>
> I was?  ;-)  I admit to finding __iterator__ initially unintuitive, but I'm not sure how you got that from reading the testcase.
>
Heh, ok, sorry if you are not confused.

The correct test for the current behavior would be to add the "foo"
property on the iterable and assert that index == 1 at the end of the
test.

Either way, you should make an assertion about the value of |index|
after iteration stops.

> > and this comment:
> > http://developer.mozilla.org/en/docs/Talk:New_in_JavaScript_1.7#Syntax_for_replacing_native_iterators.3F
>
> I figured out the problem; the code there was setting __iterator__ to a Generator, not to a function which returns a Generator.  I expect this will be a fairly common problem for first-time __iterator__ users with JS 1.7.  In general I think people are going to run into initial trouble figuring out the code mechanics needed to support custom iteration using the __iterator__ property.
>
Ah, duh. I didn't read the __defineGetter__ syntax correctly.

Still, returning a Generator from obj.__iterator__ works the same way
as returning a function that returns a Generator (the python way):
> var obj = {a:1, b:2, __iterator__: function() { yield "a"; yield 2 } }
> for(var i in obj) print(i + "->" + obj[i])
a->1

> As for the problem reported here, every time I look at it I think the behavior just might be the correct behavior, but I can never manage to convince myself.  I suspect that code demonstrates a bug, although I'm not sure what the difference is between that code and some of the code in the testcases I wrote for iterators.  In any case, I believe the code in the original MDC question that spawned this, when fixed, will run into the same problem:
>
> http://whereswalden.com/files/mozilla/js-iter-maybe-bug.html
>
Huh, so it looks like IDL-defined properties always get enumerated in
a for..in loop, no matter what your custom iterator returns. Looks
like a bug to me.

Nickolay
0
Nickolay
7/30/2006 2:07:38 PM
Nickolay Ponomarev wrote:
> The correct test for the current behavior would be to add the "foo"
> property on the iterable and assert that index == 1 at the end of the
> test.

Point, and I even did so in the sibling basic-Iterator.js test.  :-\  I filed bug 346582 to add such assertions to the tests, and I'm now convinced that current behavior is buggy.

Jeff

-- 
Rediscover the Web!
http://snurl.com/get_firefox

Reclaim Your Inbox!
http://snurl.com/get_thunderbird
0
Jeff
7/30/2006 7:22:51 PM
On 7/30/06, Jeff Walden <jwalden+nmo@mit.edu> wrote:
> Nickolay Ponomarev wrote:
> > The correct test for the current behavior would be to add the "foo"
> > property on the iterable and assert that index == 1 at the end of the
> > test.
>
> Point, and I even did so in the sibling basic-Iterator.js test.  :-\  I filed bug 346582 to add such assertions to the tests, and I'm now convinced that current behavior is buggy.
>
Blake pointed me to https://bugzilla.mozilla.org/show_bug.cgi?id=346021

Is the issue with
http://whereswalden.com/files/mozilla/js-iter-maybe-bug.html filed
too?

Nickolay
0
Nickolay
7/30/2006 7:28:51 PM
Nickolay Ponomarev wrote:
> Blake pointed me to https://bugzilla.mozilla.org/show_bug.cgi?id=346021
> 
> Is the issue with
> http://whereswalden.com/files/mozilla/js-iter-maybe-bug.html filed
> too?

I suspect they're the same problem, so I'm inclined to take a wait-and-see attitude.  :-)

Jeff

-- 
Rediscover the Web!
http://snurl.com/get_firefox

Reclaim Your Inbox!
http://snurl.com/get_thunderbird
0
Jeff
7/30/2006 8:02:48 PM
I notice this issue got fixed in recent nightlies of Firefox 2.0.  But
I'm experiencing a different issue which makes me wonder: is it not
possible to override the iterator on an element's prototype?

I experimented with modifying HTMLCollection.prototype.__iterator__
with my custom code, but when I do so, a for..in loop runs
indefinitely.  The first few results are the elements I expected, but
each result thereafter is undefined.

This makes me wonder: how can one distinguish between Foo.prototype as
the ancestor of all instances of Foo *and* Foo.prototype as an ordinary
object?  In other words, what if I just want to iterate over all the
properties that are defined in Foo.prototype?

I haven't seen this issue addressed anywhere else.  Can someone
enlighten me?

Cheers,
Andrew


Jeff Walden wrote:
> Nickolay Ponomarev wrote:
> > Blake pointed me to https://bugzilla.mozilla.org/show_bug.cgi?id=346021
> >
> > Is the issue with
> > http://whereswalden.com/files/mozilla/js-iter-maybe-bug.html filed
> > too?
>
> I suspect they're the same problem, so I'm inclined to take a wait-and-see attitude.  :-)
> 
> Jeff

0
savetheclocktower
8/2/2006 2:50:39 PM
savetheclocktower@gmail.com wrote:


> This makes me wonder: how can one distinguish between Foo.prototype as
> the ancestor of all instances of Foo *and* Foo.prototype as an ordinary
> object?  In other words, what if I just want to iterate over all the
> properties that are defined in Foo.prototype?

Well you simply need to choose the object you are interested in in the 
for..in loop e.g.
   for (var propertyName in Foo.prototype) { }
or
   for (var propertyName in someFoo) {}
Or where else do you want to distinguish?

-- 

	Martin Honnen
	http://JavaScript.FAQTs.com/
0
Martin
8/2/2006 3:57:25 PM
I've answered my own question, but I'll rephrase it:

Say I've got a var foo that's an instance of object Foo. My concern was
that any change I made to Foo.prototype.__iterator__ (which foo
inherits) would affect the Foo.prototype *instance*, which is rarely
what I would want to happen.

The way around this is to check "this == Foo.prototype" -- which feels
dirty, but works:


Foo.prototype.__iterator__ = function(keysOnly) {
  for (var propName in this) {
    if (propName == "bar" && this != Foo.prototype) { continue; }
    yield propName;
  }
  throw StopIteration;
};


For introspection's sake, I don't want to hide any properties if I'm
enumerating Foo.prototype.

But this raises another issue: how do you use the "vanilla" for..in
loop within an iterator? The code above won't work, because "for (var
propName in this)" invokes the iterator you're already in, and you'll
get an infinite recursion error.  In other words, the native Object
iterator is being shadowed by the custom iterator.

This works, though:


Foo.prototype.__iterator__ = function(keysOnly) {
  var iter = Object.prototype.__iterator__.apply(this, arguments);
  for (var propName in iter) {
    if (propName == "bar" && this != Foo.prototype) { continue; }
    yield propName;
  }
  throw StopIteration;
};


So this is the solution: enumerate using Object.prototype.__iterator__
instead.  This also feels dirty.

I might be doing this the hard way -- please let me know if I am -- but
otherwise it seems that this could use some smoothing out.  By the time
we hit ES4, this might be solved with the "intrinsic" namespace [1].
If not we'd be faced with a problem: even though Object.prototype would
finally be fair game, Object.prototype.__iterator__ would not.  (Though
it would be silly to redefine it in the first place.)

Cheers,
Andrew

[1] http://developer.mozilla.org/es4/proposals/intrinsic_namespace.html



Martin Honnen wrote:
> savetheclocktower@gmail.com wrote:
>
>
> > This makes me wonder: how can one distinguish between Foo.prototype as
> > the ancestor of all instances of Foo *and* Foo.prototype as an ordinary
> > object?  In other words, what if I just want to iterate over all the
> > properties that are defined in Foo.prototype?
>
> Well you simply need to choose the object you are interested in in the
> for..in loop e.g.
>    for (var propertyName in Foo.prototype) { }
> or
>    for (var propertyName in someFoo) {}
> Or where else do you want to distinguish?
> 
> -- 
> 
> 	Martin Honnen
> 	http://JavaScript.FAQTs.com/

0
savetheclocktower
8/2/2006 8:23:46 PM
Reply:

Similar Artilces:

Default.js or default.vbs not found
I just installed the Microsoft visual Studio.Net and want to create a new solution. But the following message displayed "Default.js or default.vbs not found in C:\Program Files\Microsoft Visual Studio .Net\Vb7\VB Wizards\WebApplication\Scripts\1028" Could anyone tell me where can I load the default.js or default.vbs I know this is a really old post, but I just thought I'd reply since I had this same problem and was able to fix it. First try the solution offered by Microsoft at http://support.microsoft.com/default.aspx?scid=kb;EN-US;313515. That didn't work for me but as I dug...

Replacing Default.aspx as default document
I'm using a different default file for folders. I need to use MyPage.aspx as a default so if someone loads /Folder it will load up MyPage.aspx instead of Default.aspx. I configured IIS to do this properly but changing the documents setting but I don't knwo where to change this on the local VS asp.net development server. When I go to /Folder i get a directory listing instead of executing MyPage.aspx.   Try setting the enable Directory Listing to false in IISVikram www.vikramlakhotia.comPlease mark the answer if it helped you It's not an IIS problem. IIS works perfectly. ...

Merging dev-tech-layout into dev-platform
Today I found out that I had missed a post from David Baron on dev-tech-layout, because I had no idea that this list exists. I think dev-platform is a better place to have the conversation related to the layout module (people are already having discussions about other modules over there). Does anybody have any objections? Cheers, Ehsan ...

Merging dev-tech-layout into dev-platform
Today I found out that I had missed a post from David Baron on dev-tech-layout, because I had no idea that this list exists. I think dev-platform is a better place to have the conversation related to the layout module (people are already having discussions about other modules over there). Does anybody have any objections? Cheers, Ehsan ...

superreview granted: [Bug 256663] old default plugin/new plugin placeholder can both appear on same page : [Attachment 157081] Never show the default plugin replacement if the default plugin is still
David Baron <dbaron@dbaron.org> has granted David Baron <dbaron@dbaron.org>'s request for superreview: Bug 256663: old default plugin/new plugin placeholder can both appear on same page http://bugzilla.mozilla.org/show_bug.cgi?id=256663 Attachment 157081: Never show the default plugin replacement if the default plugin is still enabled. http://bugzilla.mozilla.org/attachment.cgi?id=157081&action=edit ...

Use js/TypeDecls.h for basic JS engine type declarations
Hi, In a recent thread ("Stop #including jsapi.h everywhere!"), I wrote the following. > Next time you're thinking of adding a |#include "jsapi.h"| statement, > please think about whether a forward declaration would suffice -- i.e. > if you are only using public JS types (i.e. not functions), and only > using them as pointers, references, or parameters in function > declarations. (Forward-declaring JS_PUBLIC_API types is harder; ask > me for help if you need to do that.) > > [BTW, you might think "these popular forward declar...

sort: mail default (mailWindowOverlay.js) or Mailbox Default (INBOX.MSF)
I see from the MSF definitions (in any given mailbox) that B0=sortType, and is used as follows (from 1.5): SORT BY DATE DATE @$${51{@ [1:^9E(^B0=12)] @$$}51}@ SORT BY RECIEVED @$${51{@ [1:^9E(^B0=15)] @$$}51}@ Above the significance to me seems to be that a "serialized" action (launching mail, changing sort, closing mail) gets appended to the MSF, which includes the last chosen option stored, such as View | Sort | Order Received (sortType == nsMsgViewSortType.byId in mailWindowOverlay.js). On a newly installed Mozilla 1.5 system, I can change the last [1...

How to re-add default search engines and reset to default preferences on every start?
As title. From this mine thread posted in Mozillazine forum: http://forums.mozillazine.org/viewtopic.php?t=1287715 On Jun 9, 1:33=A0pm, Lucas Malor wrote: > As title. From this mine thread posted in Mozillazine forum: > > http://forums.mozillazine.org/viewtopic.php?t=3D1287715 Does not exists any solution for my problem? ...

Call js from 1 js to other js
Hi to all developers, I have two javascript file 1 Validation.js 2 Date.js there are some functions in the file I wanted to know how can i add the reference of Date.js file in Validation.js . because if i want to call a function of date.js in validation.js then i need to copy the function from date.js and paste it in validation.js to work   help me..     Imran Khan You can't copy pieces of one into the other. You'd need to include both files into the page. NC...   Once both the files are included onto the page, every function is accessibl...

superreview requested: [Bug 364297] Change default home page search and default search engine for Fx 2. 0 series
Gavin Sharp <gavin.sharp@gmail.com> has asked Benjamin Smedberg [:bs] (bsmedberg@) <benjamin@smedbergs.us> for superreview: Bug 364297: Change default home page search and default search engine for Fx 2.0 series https://bugzilla.mozilla.org/show_bug.cgi?id=3D364297 Attachment 252951: patch https://bugzilla.mozilla.org/attachment.cgi?id=3D252951&action=3Dedit ------- Additional Comments from Gavin Sharp <gavin.sharp@gmail.com> The approach I took in this patch is the following:=0D =0D 1) Create a new per-profile pref folder that takes precedence over all cur...

superreview granted: [Bug 410946] Crash in JS engine aborting applet making Java/JS calls : [Attachment 305554] Fix.
Boris Zbarsky (reviews very slow until May) <bzbarsky@mit.edu> has granted Johnny Stenback (:jst) <jst@mozilla.org>'s request for superreview: Bug 410946: Crash in JS engine aborting applet making Java/JS calls https://bugzilla.mozilla.org/show_bug.cgi?id=3D410946 Attachment 305554: Fix. https://bugzilla.mozilla.org/attachment.cgi?id=3D305554&action=3Dedit ------- Additional Comments from Boris Zbarsky (reviews very slow until May) <bzbarsky@mit.edu> Could you add documentation to nsIObjectFrame which says which of the metho= ds might destroy the frame? ...

superreview requested: [Bug 73869] Installer
benc@chuang.net has asked Daniel Veditz <dveditz@cruzio.com> for superreview: Bug 73869: Installer - all-proxy.js is appended, not replaced http://bugzilla.mozilla.org/show_bug.cgi?id=73869 Attachment 148052: over-writes all-proxy.js, rather than appends http://bugzilla.mozilla.org/attachment.cgi?id=148052&action=edit ...

superreview granted: [Bug 364297] Change default home page search and default search engine for Fx 2. 0 series
Benjamin Smedberg [:bs] (bsmedberg@) <benjamin@smedbergs.us> has granted G= avin Sharp <gavin.sharp@gmail.com>'s request for superreview: Bug 364297: Change default home page search and default search engine for Fx 2.0 series https://bugzilla.mozilla.org/show_bug.cgi?id=3D364297 Attachment 252951: patch https://bugzilla.mozilla.org/attachment.cgi?id=3D252951&action=3Dedit ------- Additional Comments from Benjamin Smedberg [:bs] (bsmedberg@) <benjamin@smedbergs.us> >Index: browser/base/Makefile.in=0D =0D > ifndef MOZ_BRANDING_DIRECTORY=0D > ...

superreview granted: [Bug 73869] Installer
Daniel Veditz <dveditz@cruzio.com> has granted benc@chuang.net's request for superreview: Bug 73869: Installer - all-proxy.js is appended, not replaced http://bugzilla.mozilla.org/show_bug.cgi?id=73869 Attachment 148052: over-writes all-proxy.js, rather than appends http://bugzilla.mozilla.org/attachment.cgi?id=148052&action=edit ------- Additional Comments from Daniel Veditz <dveditz@cruzio.com> sr=dveditz ...

Web resources about - Replacing default __iterator__? - mozilla.dev.tech.js-engine

Iterator - Wikipedia, the free encyclopedia
Various types of iterators are often provided via a container's interface. Though the interface and semantics of a given iterator are fixed, ...

Price Drop: iterator
iterator 1.0.1 Device: iOS iPad Only Category: Music Price: Free, Version: 1.0.1 ( iTunes ) Description: iterator is an inspiring sample based ...

How C++ Reverse Iterators Represent Boundaries
... pointers can be used to represent boundaries. Let's continue by looking more closely at how these representations interact with reverse iterators. ...


<?php class IteratorTest implements Iterator { private $_items = array(1,2,3 - Pastebin.com
<?php class IteratorTest implements Iterator { private $_items = array(1,2,3 - Pastebin.com

Hiding iterator boilerplate behind a Boost facade
Contents Filling in missing methods. Python Filling in missing methods. C++ Enter Boost iterators Using boost::iterator_facade Templates ...

A Classic Example That Off-The-End Iterators Can Simplify
Let's examine a programming problem that Edsger Dijkstra calls "the problem of the Dutch national flag."

How To Use Reverse Iterators Without Getting Confused
This week we'll look at a concrete example of how to use reverse iterators.

Iterators and iostreams
In a previous post, I bemoaned the fact that the C++ iterators that perform stream I/O use the insertion and extraction operators, making them ...

Resources last updated: 11/29/2015 11:46:25 PM