Issue #16270 has been updated by Dan0042 (Daniel DeLorme).
Of all Hash methods, only select/reject/select!/reject!/keep_if/delete_if have that behavior. That's fairly inconsistent, but more importantly it doesn't seem like this inconsistency is on purpose. There is no test for this case in test/ruby/test_hash.rb.
I tried changing `rb_yield_values(2` to `rb_yield(rb_assoc_new(` and I got only one failure in the specs, in test_delete_if, because of `h.delete_if {|*a|` where `*a` becomes `[[1,"one"]]` instead of `[1,"one"]`. And this is more related to #16166 than the current issue.
----------------------------------------
Bug #16270: Strange behavior on Hash's #each and #select method.
https://bugs.ruby-lang.org/issues/16270#change-82240
* Author: zw963 (Wei Zheng)
* Status: Closed
* Priority: Normal
* Assignee:
* Target version:
* ruby -v: 2.6.3
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
The 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}
# The following is p's output content. We can see that e is a hash element, and is converted into an array object.
# This is expected behavior maybe. Anyway, a hash is the 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 is e's output this time different from each?
"246"
"247"
"248"
```
The 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;
}
```
The 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, and don't know why the above two Hash methods lack consistency. But I think it confuses me a little.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>