Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

detecting Iterator() usage in custom iterator

3 views
Skip to first unread message

Myk Melez

unread,
Oct 11, 2010, 8:17:28 PM10/11/10
to
Jetpack SDK code has been inspecting stack traces within custom
iterators (i.e. __iterator__ methods) to determine whether or not
Iterator() was used, but that broke on the trunk a month or so ago, as
Iterator() disappeared from those traces.

We'd previously checked Function.caller, but that isn't available in
strict mode (to which we're switching our codebase).

Is there any other way to detect that a custom iterator was called via
Iterator()? We'd like our custom iterators to behave the same as
standard object iterators, including returning [key, value] pairs when
Iterator() is used.

-myk

Andreas Gal

unread,
Oct 11, 2010, 8:55:30 PM10/11/10
to Myk Melez, dev-tech-...@lists.mozilla.org

Could you post the stack trace before and after? That would help I think.

Andreas

> _______________________________________________
> dev-tech-js-engine mailing list
> dev-tech-...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-tech-js-engine

Donny Viszneki

unread,
Oct 12, 2010, 2:53:44 PM10/12/10
to Myk Melez, dev-tech-...@lists.mozilla.org
I think a better solution than checking the stack or Function.caller
is to override the Iterator function. Something like:

Iterator = (function(Iterator){return function Iterator(o){if (o
instanceof Whatever) { /* special Iterator() behavior */} else {/*
normal behavior */}}})(Iterator)

The purpose of passing Iterator as an argument here is to allow the
"normal behavior" path to invoke the Iterator function being
overridden.

> _______________________________________________
> dev-tech-js-engine mailing list
> dev-tech-...@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-tech-js-engine
>

--
http://codebad.com/

Myk Melez

unread,
Oct 12, 2010, 8:25:52 PM10/12/10
to Andreas Gal
On 10/11/2010 05:55 PM, Andreas Gal wrote:
> Could you post the stack trace before and after? That would help I think.

Here are the first few lines of a stack trace (Error().stack) from
Firefox 3.6:

Error()@:0
()@file:///mnt/hgfs/myk/Projects/jsdk/packages/jetpack-core/lib/securable-module.js
-> resource://jetpack-core-jetpack-core-lib/securable-module.js ->
resource://jetpack-core-jetpack-core-tests/test-iterator.js:7
Iterator([object Object])@:0
([object
Object])@file:///mnt/hgfs/myk/Projects/jsdk/packages/jetpack-core/lib/securable-module.js
-> resource://jetpack-core-jetpack-core-lib/securable-module.js ->
resource://jetpack-core-jetpack-core-tests/test-iterator.js:13


Here are the first few lines of one from a Firefox 4 trunk build:

()@resource://jetpack-core-jetpack-core-lib/securable-module.js ->
resource://jetpack-core-jetpack-core-lib/securable-module.js ->
resource://jetpack-core-jetpack-core-tests/test-iterator.js:7
([object
Object])@resource://jetpack-core-jetpack-core-lib/securable-module.js ->
resource://jetpack-core-jetpack-core-lib/securable-module.js ->
resource://jetpack-core-jetpack-core-tests/test-iterator.js:13

-myk

Myk Melez

unread,
Oct 13, 2010, 6:34:21 PM10/13/10
to Donny Viszneki
On 10/12/2010 11:53 AM, Donny Viszneki wrote:
> I think a better solution than checking the stack or Function.caller
> is to override the Iterator function.

Thanks for the suggestion! It's what I've done (over in bug 597004) via
a custom Iterator function that passes an extra parameter to custom
iterator methods to specify that the method is being called via
Iterator, i.e. something like:

(function(DefaultIterator) {
return function Iterator(obj, keysOnly) {
if ("__iterator__" in obj && !keysOnly)
return obj.__iterator__.call(obj, false, true);
return DefaultIterator(obj, keysOnly);
};
})(Iterator);

Objects with custom iterator methods that want to support Iterator then
do something like:

this.__iterator__ = function (keysOnly, keysVals) {
for each (let [key, val] in customSet)
yield keysVals ? [key, val] : keysOnly ? key : val;
};

Perhaps it would be useful to add such a second parameter to the native
Iterator function.

-myk

0 new messages