|
From: <bc...@wo...> - 2001-03-28 08:08:56
|
[Jim Adrig] >I wasn't sure whether to post to 'jython-user': but I think this brings >up something relevant for 'dev'... It is not always easy to decide. Even when the orginal poster chose absolutely right, the followups may move the discussion into new territory. Anyway, it is a minor issue. >I have just found a problem with my Java/Jython code that was driving me >crazy! It turns out it was because of the use of >'System.identityHashCode(key)' instead of 'key.hashCode()' in >PyStringMap. When I change the 3 occurences to 'key.hashCode()' all my >problems disappear. > >I have included some test code below that demonstrates the problem. Am I >doing something I shouldn't be ? Yes, the name arguments to __findattr__ and __setattr__ must be interned strings. Almost the entire attribute lookup implementation assume this to be true for the speed improvement that it gives us. http://www.jython.org/docs/api/org/python/core/PyObject.html >If not, then the question is: is this a bug? Or will I create one by >changing the code? In general I have been trying to extend the Jython >classes when necessary to add/change functionality. > >But I'm not sure what to do here: I can't see a reason in this case to >use 'identityHashCode' instead of 'hashCode()' since 'key' is only a >'String'. (In other classes that use PyObjects I can sort of see why you >might need 'identityHashCode' (?) ) It goes deeper than just PyStringMap. A very common pattern is an implementation of __findattr__(..) like this: public PyObject __findattr__(String name) { if (name == "__dict__") return __dict__; if (name == "__name__") return new PyString(__name__); if (name == "__bases__") return __bases__; ... } >If this can be a patch to Jython, I will leave my code in until I get a >new version. If not, I may try to reimplement the 'PyStringMap' method >in an extending class (?) or figure out some other workaround. This is a correct way to set/get attributes: classInstance.__setattr__( key1.intern(), new PyString("In my code this is actually a PyList object..." )); // Looking it up using the original key1 works: PyObject findIt1 = classInstance.__findattr__(key1.intern()); System.out.println("Using 'key1' this is OK :" + findIt1); // Interned key2 also works PyObject findIt2 = classInstance.__findattr__(key2.intern()); System.out.println("And interned 'key2' also works :" + findIt2); >Thanks (Finn: nice job on the Complex Number bug !) You're welcome. regards, finn |