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

List handling in CVS HEAD Rhino

10 views
Skip to first unread message

Attila Szegedi

unread,
Dec 27, 2007, 9:46:57 AM12/27/07
to dev-tech-js-...@lists.mozilla.org
I have a custom wrap factory that wraps java.util.List instances into
a Scriptable that allows access by index, i.e. "list[1]". It
implements getIds() method appropriately to return an array of
integers for the list, providing the usual semantics where you can
then iterate over the list as you could over a native array:

for(i in list) { doSomethingWith(list[i]); }

This worked until recently. Now, Rhino will ignore getIds() if the
wrapped object implements java.lang.Iterable, and for..in will iterate
over values:

for(i in x) { java.lang.System.out.println(i); }

when "x" is a java.util.List will print the values, and will no longer
print indices.

Shouldn't getIds() still have priority? Also, what'd be the easiest
way to restore the original behaviour in my custom wrappers? Also, is
the new behaviour desirable at all? I.e. a for..in over a native Java
array will keep iterating over the indices, as it always did, which
creates a bit of inconsistency.

So, while we're at that, shouldn't we allow java.util.List instances
to be treated identically to native Java arrays, similar to
NativeJavaArray class? I know List is a Java 2 interface, and thus
didn't exist back when Rhino (and LiveConnect) were originally
created, but I think we should catch up with times...

Attila.

David P. Caldwell

unread,
Dec 28, 2007, 8:33:07 PM12/28/07
to
On Dec 27, 9:46 am, Attila Szegedi <szege...@gmail.com> wrote:
> Now, Rhino will ignore getIds() if the
> wrapped object implements java.lang.Iterable, and for..in will iterate
> over values:
>
> for(i in x) { java.lang.System.out.println(i); }
>
> when "x" is a java.util.List will print the values, and will no longer
> print indices.
>
> Shouldn't getIds() still have priority?

That would be my vote, now that you mention it. In my view, it makes
sense to have:

for each (i in x) { ... }

iterate over the values, but for (i in x) should iterate over the
indices, I'd think.

> So, while we're at that, shouldn't we allow java.util.List instances
> to be treated identically to native Java arrays, similar to
> NativeJavaArray class? I know List is a Java 2 interface, and thus
> didn't exist back when Rhino (and LiveConnect) were originally
> created, but I think we should catch up with times...

Not sure here. LiveConnect is quite mature -- I'd think we'd want to
urge whoever controls the LiveConnect spec to "catch up with the
times" and then catch up with them. But I could be persuaded.

-- David P. Caldwell
http://www.inonit.com/

Norris Boyd

unread,
Dec 30, 2007, 9:36:03 PM12/30/07
to
On Dec 27, 9:46 am, Attila Szegedi <szege...@gmail.com> wrote:

In general I'm pretty hesitant to change behavior in Rhino that
affects backwards compatibility. My thinking in making the change to
the way Interables are handled was that I figured people weren't too
dependent on the previous behavior of iterating over the method
properties of an Iterable because it's of limited usefulness. However,
I didn't think of your case of a custom wrap factory. Thanks for
pointing this case out--I agree that this is not a good change to make
as is.

Perhaps we need some new top-level functions that can take Java
Iterables and make them JavaScript iterators, Java Lists and make them
JavaScript Arrays, and Java Maps and make them JavaScript "hashes".
Then the change is under the control of the script writer and avoids
problems with backwards compatibility. Thoughts?

--Norris

Norris Boyd

unread,
Dec 30, 2007, 9:38:07 PM12/30/07
to

The LiveConnect spec was created by people at Netscape. I don't know
that there's anyone who owns it in any sense now. I think Rhino is
probably the main user of JavaScript-to-Java communication.

>
> -- David P. Caldwellhttp://www.inonit.com/

Norris Boyd

unread,
Jan 3, 2008, 1:39:44 PM1/3/08
to
I've made changes to Rhino such that its default behavior is now only
to treat Iterables or Iterators specially when they are arguments to
the new Iterator constructor:

js> m = new java.util.HashMap()
{}
js> m.put("a",1)
null
js> m.put("b",2)
null
js> m
{a=1.0, b=2.0}
js> for (i in m.values()) print(i)
notifyAll
removeAll
containsAll
contains
empty
equals
notify
class
isEmpty
add
size
iterator
clear
wait
retainAll
toString
hashCode
toArray
addAll
getClass
remove
js> for (i in Iterator(m.values())) print(i)
1.0
2.0
js> for (i in Iterator(m.values().iterator())) print(i)
1.0
2.0
js>

Since Iterator is a new addition for 1.7, there are no issues for
backwards compatibility.

This still leaves open the possibility of top-level functions to wrap
Maps and Lists as JavaScript Objects and Arrays.

--N

0 new messages