summaryrefslogtreecommitdiff
path: root/enum.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-20 15:06:56 (GMT)
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-09-20 15:06:56 (GMT)
commitabe75149d14d3286d3051c9e961ab6473a243a19 (patch)
treef33ad9fcd4569f51d7f0b85fefb751597211438d /enum.c
parente76eebd79be9fa3cb59d0ea6e4ce8214cc6e56ad (diff)
Enumerable#to_h with block and so on
[Feature #15143] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64794 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'enum.c')
-rw-r--r--enum.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/enum.c b/enum.c
index 127b839..d75e9d7 100644
--- a/enum.c
+++ b/enum.c
@@ -613,38 +613,42 @@ enum_to_a(int argc, VALUE *argv, VALUE obj)
static VALUE
enum_to_h_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
{
- VALUE key_value_pair;
ENUM_WANT_SVALUE();
rb_thread_check_ints();
- key_value_pair = rb_check_array_type(i);
- if (NIL_P(key_value_pair)) {
- rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
- rb_builtin_class_name(i));
- }
- if (RARRAY_LEN(key_value_pair) != 2) {
- rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
- RARRAY_LEN(key_value_pair));
- }
- rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
- return Qnil;
+ return rb_hash_set_pair(hash, i);
+}
+
+static VALUE
+enum_to_h_ii(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
+{
+ rb_thread_check_ints();
+ return rb_hash_set_pair(hash, rb_yield_values2(argc, argv));
}
/*
* call-seq:
- * enum.to_h(*args) -> hash
+ * enum.to_h(*args) -> hash
+ * enum.to_h(*args) {...} -> hash
*
* Returns the result of interpreting <i>enum</i> as a list of
* <tt>[key, value]</tt> pairs.
*
* %i[hello world].each_with_index.to_h
* # => {:hello => 0, :world => 1}
+ *
+ * If a block is given, the results of the block on each element of
+ * the array will be used as pairs.
+ *
+ * (1..5).to_h {|x| [x, x ** 2]}
+ * #=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
*/
static VALUE
enum_to_h(int argc, VALUE *argv, VALUE obj)
{
VALUE hash = rb_hash_new();
- rb_block_call(obj, id_each, argc, argv, enum_to_h_i, hash);
+ rb_block_call_func *iter = rb_block_given_p() ? enum_to_h_ii : enum_to_h_i;
+ rb_block_call(obj, id_each, argc, argv, iter, hash);
OBJ_INFECT(hash, obj);
return hash;
}