From: Mauricio Fernandez Date: 2006-08-13T09:38:17+09:00 Subject: Re: PATCH to make internal Hash class retain order... On Sun, Aug 13, 2006 at 09:08:14AM +0900, Hal Fulton wrote: > dblack@wobblini.net wrote: > >Could it be implemented as an extension that redefines Hash? > > > > That's a very interesting question. I'd like to think so. > > I'd assume that the *parser* at least retains the oreder > in which it sees the elements of the literal (long enough > to pass them to the "guts" of Hash). I don't think this is easily implementable as an extension without patching the interpreter. The order of the associations in the literal is indeed preserved, since they're put in a linked list inside the NODE_HASH. However, the latter is evaluated in rb_eval, so the OP would need to patch that, using at least something like (untested) --- eval.c.orig 2006-08-13 02:28:59.000000000 +0200 +++ eval.c 2006-08-13 02:31:39.000000000 +0200 @@ -3750,22 +3750,23 @@ break; case NODE_HASH: { NODE *list; - VALUE hash = rb_hash_new(); + VALUE hash = rb_funcall(rb_const_get_at(rb_cObject, rb_intern("Hash")), + rb_intern("new"), 0, 0); VALUE key, val; list = node->nd_head; while (list) { key = rb_eval(self, list->nd_head); list = list->nd_next; if (list == 0) rb_bug("odd number list for Hash"); val = rb_eval(self, list->nd_head); list = list->nd_next; - rb_hash_aset(hash, key, val); + rb_funcall(hash, rb_intern("[]="), 2, key, val); } result = hash; } break; in order to turn literals into ordered hashes if Hash is replaced. Even if you cache the IDs, the speed impact will probably be significant; it's too late to time this now. -- Mauricio Fernandez - http://eigenclass.org - singular Ruby