From: shevegen@... Date: 2019-10-22T16:29:19+00:00 Subject: [ruby-core:95468] [Ruby master Bug#16270] Strange behavior on Hash's #each and #select method. Issue #16270 has been updated by shevegen (Robert A. Heiler). I am not entirely sure where there is a lack of consistency or why the C code is necessary. I assume that you may have been confused about Kernel#p perhaps? It is rare that people combine .select with p, whereas this behaviour is more frequently seen with .each, where people may output all or some elements. What helps me personally is when I "split" up the Hash into "key" and "value" pairs, such as: sample_hash.select {|key, value| p key } The above still does not make a whole lot of sense to me, but from the code alone I think it became more clear what you, as a user of ruby, actually want to do. Of course I may have misunderstood you as well. (The reason why I wrote that I do not see a lack of consistency is because .each and .select have different behaviour on purpose. What I often do is modify the internal dataset of a class, before I may then go on to report it to the user after the dataset was modified. It's a bit like MVC but nowhere as strict as MVC separates stuff.) ---------------------------------------- Bug #16270: Strange behavior on Hash's #each and #select method. https://bugs.ruby-lang.org/issues/16270#change-82236 * Author: zw963 (Wei Zheng) * Status: Open * Priority: Normal * Assignee: * Target version: * ruby -v: 2.6.3 * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN ---------------------------------------- Following is some example code: ``` ruby sample_hash = { "246" => { "price" => "8000", "note" => "" }, "247" => { "price" => "8000", "note" => "" }, "248" => { "price" => "8000", "note" => "" } } sample_hash.each {|e| p e} # following is p output content, we can see e is a hash element, and convert to a array object. # this is expected behavior maybe, anyway, hash is same as a nested array. ["246", {"price"=>"8000", "note"=>""}] ["247", {"price"=>"8000", "note"=>""}] ["248", {"price"=>"8000", "note"=>""}] sample_hash.select {|e| p e } # Wired, why this time, e output different with each? "246" "247" "248" ``` Following is source code for **each** ```c static VALUE rb_hash_each_pair(VALUE hash) { RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); if (rb_block_arity() > 1) rb_hash_foreach(hash, each_pair_i_fast, 0); else rb_hash_foreach(hash, each_pair_i, 0); return hash; } ``` Following is source code for **select** ```c VALUE rb_hash_select(VALUE hash) { VALUE result; RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); result = rb_hash_new(); if (!RHASH_EMPTY_P(hash)) { rb_hash_foreach(hash, select_i, result); } return result; } ``` I don't understand C well, don't know why lack of consistency for above two Hash method, but, i think it is a little confuse me. Thank you. -- https://bugs.ruby-lang.org/ Unsubscribe: