Feature #14788 ยป hash_keys_block.patch
| 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
|
||