summaryrefslogtreecommitdiff
path: root/include/ruby/internal/intern/enum.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ruby/internal/intern/enum.h')
-rw-r--r--include/ruby/internal/intern/enum.h42
1 files changed, 41 insertions, 1 deletions
diff --git a/include/ruby/internal/intern/enum.h b/include/ruby/internal/intern/enum.h
index e1d65b5c9a..215ad82672 100644
--- a/include/ruby/internal/intern/enum.h
+++ b/include/ruby/internal/intern/enum.h
@@ -26,7 +26,47 @@
RBIMPL_SYMBOL_EXPORT_BEGIN()
/* enum.c */
-VALUE rb_enum_values_pack(int, const VALUE*);
+
+/**
+ * Basically identical to rb_ary_new_form_values(), except it returns something
+ * different when `argc` < 2.
+ *
+ * @param[in] argc Number of objects of `argv`.
+ * @param[in] argv Arbitrary objects.
+ * @retval RUBY_Qnil `argc` is zero.
+ * @retval argv[0] `argc` is one.
+ * @retval otherwise Otherwise.
+ *
+ * @internal
+ *
+ * What is this business? Well, this function is about `yield`'s taking
+ * multiple values. Consider following user-defined class:
+ *
+ * ```ruby
+ * class Foo
+ * include Enumerable
+ *
+ * def each
+ * yield :q, :w, :e, :r
+ * end
+ * end
+ *
+ * Foo.new.each_with_object([]) do |i, j|
+ * j << i # ^^^ <- What to expect for `i`?
+ * end
+ * ```
+ *
+ * Here, `Foo#each_with_object` is in fact `Enumerable#each_with_object`, which
+ * doesn't know what would be yielded. Yet, it has to take a block of arity 2.
+ * This function is used here, to "pack" arbitrary number of yielded objects
+ * into one.
+ *
+ * If people want to implement their own `Enumerable#each_with_object` this API
+ * can be handy. Though @shyouhei suspects it is relatively rare for 3rd party
+ * extension libraries to have such things. Also `Enumerable#each_entry` is
+ * basically this function exposed as a Ruby method.
+ */
+VALUE rb_enum_values_pack(int argc, const VALUE *argv);
RBIMPL_SYMBOL_EXPORT_END()