aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--hash.c29
-rw-r--r--test/ruby/test_hash.rb15
3 files changed, 49 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ecc72cb1f..d3fcbfcd32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Fri Jun 12 17:34:14 2015 Wojciech Mach <wojtek@wojtekmach.pl>
+
+ * hash.c (rb_hash_fetch_values): add `Hash#fetch_values`.
+ [Feature #10017] [Fix GH-776]
+
Fri Jun 12 16:28:17 2015 Radan Skoric <radan.skoric@gmail.com>
* array.c (rb_ary_bsearch_index): Implement Array#bsearch_index
diff --git a/hash.c b/hash.c
index 60e980763c..80de813b98 100644
--- a/hash.c
+++ b/hash.c
@@ -1275,6 +1275,34 @@ rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
return result;
}
+/*
+ * call-seq:
+ * hsh.fetch_values(key, ...) -> array
+ * hsh.fetch_values(key, ...) { |key| block } -> array
+ *
+ * Returns an array containing the values associated with the given keys
+ * but also raises <code>KeyError</code> when one of keys can't be found.
+ * Also see <code>Hash#values_at</code> and <code>Hash#fetch</code>.
+ *
+ * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
+ *
+ * h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
+ * h.fetch_values("cow", "bird") # raises KeyError
+ * h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
+ */
+
+VALUE
+rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
+{
+ VALUE result = rb_ary_new2(argc);
+ long i;
+
+ for (i=0; i<argc; i++) {
+ rb_ary_push(result, rb_hash_fetch(hash, argv[i]));
+ }
+ return result;
+}
+
static int
select_i(VALUE key, VALUE value, VALUE result)
{
@@ -4001,6 +4029,7 @@ Init_Hash(void)
rb_define_method(rb_cHash,"keys", rb_hash_keys, 0);
rb_define_method(rb_cHash,"values", rb_hash_values, 0);
rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1);
+ rb_define_method(rb_cHash,"fetch_values", rb_hash_fetch_values, -1);
rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
rb_define_method(rb_cHash,"delete", rb_hash_delete_m, 1);
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 86305ee958..f6046cb428 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -498,6 +498,21 @@ class TestHash < Test::Unit::TestCase
assert_equal ['three', nil, 'one', 'nil'], res
end
+ def test_fetch_values
+ res = @h.fetch_values
+ assert_equal(0, res.length)
+
+ res = @h.fetch_values(3, 2, 1, nil)
+ assert_equal(4, res.length)
+ assert_equal %w( three two one nil ), res
+
+ assert_raises KeyError do
+ @h.fetch_values(3, 'invalid')
+ end
+
+ res = @h.fetch_values(3, 'invalid') { |k| k.upcase }
+ assert_equal %w( three INVALID ), res
+ end
def test_invert
h = @h.invert