1

The Ruby documentation makes a statement about Hash#values:

Hashes enumerate their values in the order that the corresponding keys were inserted.

This also appears to be true for Hash#keys, but that is not documented.

Is this likely to remain true? And is it true for all key sets?

sawa
  • 165,429
  • 45
  • 277
  • 381
peterk
  • 5,136
  • 6
  • 33
  • 47
  • Short answer, yes. The enumeration order follows several other languages. It's the order in which they were inserted. However, that order could be changed by yourself after initialisation, in which case, it would follow the new order. – Cjmarkham Oct 14 '18 at 17:21
  • @CarlMarkham This should be an answer I would select it :) I specifically want to use this in getting hash arguments inside a method so the hash in this case will not be transformed between the caller and the method. – peterk Oct 14 '18 at 17:24
  • whether or not it's true, i have never encountered a use case for requiring ordered iteration in a hash ... why not use a normal ordered structure (an array)? – max pleaner Oct 14 '18 at 20:00
  • @maxpleaner because I am looking at the hash sent into a method invocation representing "named arguments" and Hash#keys returns the array in the enumerated order. – peterk Oct 15 '18 at 13:04
  • I don't see why you would need to see the 'named arguments' in any particular order, because you can just identify them by name ... but i won't press the point – max pleaner Oct 15 '18 at 15:58
  • @maxpleaner in ruby rake a "task" initialization takes ordered named arguments with unspecified keys (ie name of the task etc). If you add named arguments for any additional purpose the Rake task arguments need to be removed and separated from the added argumenmts. I have implemented what I need. – peterk Oct 16 '18 at 23:58

1 Answers1

0

Short answer, "unknown".

This appears to be true as of Ruby 1.9+ But so far I have not seen any explicit statement of either yes or no.

It would be nice if the docs would specify it. In the source code to the linux implementation it appears a list of key-value pairs is what is being traversed, and key, value, and key:value iterators traverse this structure and they would in this case traverse in the same order but there is no statement whether this is part of the api contract.

PK

peterk
  • 5,136
  • 6
  • 33
  • 47
  • Do you have any sources for your claims? The OP specifically asked this question because the *official documentation* is ambiguous, and does not clearly specify that iteration over keys preserves insertion order, only iteration over values. I also find your claim that it "follows most other languages" dubious, not the least because of the fact that until recently, Ruby itself made *no guarantees at all* about iteration order of hashes; this was only introduced in Ruby 1.9 in 2007, and for example, in Python dicts have only guaranteed an iteration order for less than 10 months. – Jörg W Mittag Oct 17 '18 at 19:41
  • In Java and .NET, the standard Dictionary interface makes no guarantees about iteration order, and the standard implementations of those interfaces have no defined order; you need to use specialized implementations to get a defined iteration order. In fact, recording the insertion order for later iteration is extra work and requires extra memory, making insertion, deletion, and iteration slower, so I would naturally expect that most languages would *not* make any guarantees about iteration order. – Jörg W Mittag Oct 17 '18 at 19:42
  • Also, Carl Markham already posted [this exact same answer](https://stackoverflow.com/a/52806782/2988), and then deleted it again, and I assume it is because he felt he could not sufficiently back it up. Copy&pasting his answer *again* does not make it more true. – Jörg W Mittag Oct 17 '18 at 19:44