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: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>