Project

General

Profile

Feature #14788 ยป hash_keys_block.patch

rringler (Ryan Ringler), 05/28/2018 06:13 AM

View differences:

hash.c
return ST_CONTINUE;
}
static int
keys_block_i(VALUE key, VALUE value, VALUE ary)
{
if (RTEST(rb_yield(key))) {
rb_ary_push(ary, key);
}
return ST_CONTINUE;
}
/*
* call-seq:
* hsh.keys -> array
*
* Returns a new array populated with the keys from this hash. See also
* <code>Hash#values</code>.
* <code>Hash#values</code>. If a block is given, it returns the keys for
* which the block evaluates to +true+.
*
* h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
* h.keys #=> ["a", "b", "c", "d"]
* h.keys #=> ["a", "b", "c", "d"]
# h.keys { |key| %w[a c].include?(key) } #=> ["a", "c"]
*
*/
......
st_index_t size = RHASH_SIZE(hash);
keys = rb_ary_new_capa(size);
if (size == 0) return keys;
if (ST_DATA_COMPATIBLE_P(VALUE)) {
st_table *table = RHASH(hash)->ntbl;
if (size == 0) return keys;
rb_gc_writebarrier_remember(keys);
RARRAY_PTR_USE(keys, ptr, {
size = st_keys(table, ptr, size);
});
rb_ary_set_len(keys, size);
if (rb_block_given_p()) {
rb_hash_foreach(hash, keys_block_i, keys);
}
else {
rb_hash_foreach(hash, keys_i, keys);
if (ST_DATA_COMPATIBLE_P(VALUE)) {
st_table *table = RHASH(hash)->ntbl;
rb_gc_writebarrier_remember(keys);
RARRAY_PTR_USE(keys, ptr, {
size = st_keys(table, ptr, size);
});
rb_ary_set_len(keys, size);
}
else {
rb_hash_foreach(hash, keys_i, keys);
}
}
return keys;
spec/ruby/core/hash/keys_spec.rb
h[h.keys[i]].should == h.values[i]
end
end
it "accepts a block" do
h = { 1 => "1", 2 => "2", 3 => "3", 4 => "4" }
h.keys { |key| key.odd? }.should == [1, 3]
h.keys { |key| key.even? }.should == [2, 4]
end
end
    (1-1/1)