From 03fd22a170977f23b6c75981c41b3b90b4704975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Fri, 11 Dec 2020 18:26:27 +0900 Subject: [PATCH] include/ruby/internal/iterator.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- eval.c | 64 ----- include/ruby/internal/iterator.h | 468 +++++++++++++++++++++++++++++-- 2 files changed, 451 insertions(+), 81 deletions(-) diff --git a/eval.c b/eval.c index ef98d7192e..a2cd523518 100644 --- a/eval.c +++ b/eval.c @@ -930,11 +930,6 @@ rb_jump_tag(int tag) EC_JUMP_TAG(GET_EC(), tag); } -/*! Determines if the current method is given a block. - * \retval zero if not given - * \retval non-zero if given - * \ingroup defmethod - */ int rb_block_given_p(void) { @@ -956,11 +951,6 @@ rb_keyword_given_p(void) VALUE rb_eThreadError; -/*! Declares that the current method needs a block. - * - * Raises a \c LocalJumpError if not given a block. - * \ingroup defmethod - */ void rb_need_block(void) { @@ -969,28 +959,6 @@ rb_need_block(void) } } -/*! An equivalent of \c rescue clause. - * - * Equivalent to begin .. rescue err_type .. end - * - * \param[in] b_proc a function which potentially raises an exception. - * \param[in] data1 the argument of \a b_proc - * \param[in] r_proc a function which rescues an exception in \a b_proc. - * \param[in] data2 the first argument of \a r_proc - * \param[in] ... 1 or more exception classes. Must be terminated by \c (VALUE)0. - * - * First it calls the function \a b_proc, with \a data1 as the argument. - * When \a b_proc raises an exception, it calls \a r_proc with \a data2 and - * the exception object if the exception is a kind of one of the given - * exception classes. - * - * \return the return value of \a b_proc if no exception occurs, - * or the return value of \a r_proc if otherwise. - * \sa rb_rescue - * \sa rb_ensure - * \sa rb_protect - * \ingroup exception - */ VALUE rb_rescue2(VALUE (* b_proc) (VALUE), VALUE data1, VALUE (* r_proc) (VALUE, VALUE), VALUE data2, ...) @@ -1002,10 +970,6 @@ rb_rescue2(VALUE (* b_proc) (VALUE), VALUE data1, return ret; } -/*! - * \copydoc rb_rescue2 - * \param[in] args exception classes, terminated by (VALUE)0. - */ VALUE rb_vrescue2(VALUE (* b_proc) (VALUE), VALUE data1, VALUE (* r_proc) (VALUE, VALUE), VALUE data2, @@ -1066,20 +1030,6 @@ rb_vrescue2(VALUE (* b_proc) (VALUE), VALUE data1, return result; } -/*! An equivalent of \c rescue clause. - * - * Equivalent to begin .. rescue .. end. - * - * It is the same as - * \code{cpp} - * rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError, (VALUE)0); - * \endcode - * - * \sa rb_rescue2 - * \sa rb_ensure - * \sa rb_protect - * \ingroup exception - */ VALUE rb_rescue(VALUE (* b_proc)(VALUE), VALUE data1, VALUE (* r_proc)(VALUE, VALUE), VALUE data2) @@ -1126,20 +1076,6 @@ rb_protect(VALUE (* proc) (VALUE), VALUE data, int *pstate) return result; } -/*! - * An equivalent to \c ensure clause. - * - * Equivalent to begin .. ensure .. end. - * - * Calls the function \a b_proc with \a data1 as the argument, - * then calls \a e_proc with \a data2 when execution terminated. - * \return The return value of \a b_proc if no exception occurred, - * or \c Qnil if otherwise. - * \sa rb_rescue - * \sa rb_rescue2 - * \sa rb_protect - * \ingroup exception - */ VALUE rb_ensure(VALUE (*b_proc)(VALUE), VALUE data1, VALUE (*e_proc)(VALUE), VALUE data2) { diff --git a/include/ruby/internal/iterator.h b/include/ruby/internal/iterator.h index 70ac1bb94d..3512b0ac86 100644 --- a/include/ruby/internal/iterator.h +++ b/include/ruby/internal/iterator.h @@ -20,54 +20,488 @@ * extension libraries. They could be written in C++98. * @brief Block related APIs. */ +#include "ruby/internal/attr/deprecated.h" #include "ruby/internal/attr/noreturn.h" #include "ruby/internal/dllexport.h" #include "ruby/internal/value.h" RBIMPL_SYMBOL_EXPORT_BEGIN() +/** + * @private + * + * @deprecated This macro once was a thing in the old days, but makes no sense + * any longer today. Exists here for backwards compatibility + * only. You can safely forget about it. + */ #define RB_BLOCK_CALL_FUNC_STRICT 1 + +/** + * @private + * + * @deprecated This macro once was a thing in the old days, but makes no sense + * any longer today. Exists here for backwards compatibility + * only. You can safely forget about it. + */ #define RUBY_BLOCK_CALL_FUNC_TAKES_BLOCKARG 1 + +/** + * Shim for block function parameters. Historically ::rb_block_call_func_t had + * only two parameters. Over time it evolved to have much more than that. By + * using this macro you can absorb such API differences. + * + * ```CXX + * // This works since 2.1.0 + * VALUE my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c)); + * ``` + */ #define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg) \ VALUE yielded_arg, VALUE callback_arg, int argc, const VALUE *argv, VALUE blockarg + +/** + * This is the type of a function that the interpreter expect for C-backended + * blocks. Blocks are often written in Ruby. But C extensions might want to + * have their own blocks. In order to do so authors have to create a separate + * C function of this type, and pass its pointer to rb_block_call(). + * + * ```CXX + * VALUE + * my_own_iterator(RB_BLOCK_CALL_FUNC_ARGLIST(y, c)) + * { + * const auto plus = rb_intern("+"); + * return rb_funcall(c, plus, 1, y); + * } + * + * VALUE + * my_own_method(VALUE self) + * { + * const auto each = rb_intern("each"); + * return rb_block_call(self, each, 0, 0, my_own_iterator, self); + * } + * ``` + */ typedef VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)); + +/** + * Shorthand type that represents an iterator-written-in-C function pointer. + */ typedef rb_block_call_func *rb_block_call_func_t; -VALUE rb_each(VALUE); -VALUE rb_yield(VALUE); +/** + * This is a shorthand of calling `obj.each`. + * + * @param[in] obj The receiver. + * @return What `obj.each` returns. + * + * @internal + * + * Does anyone still need it? This API was to use with rb_iterate(), which is + * marked deprecated (see below). Old idiom to call an iterator was: + * + * ```CXX + * VALUE recv; + * VALUE iter_func(ANYARGS); + * VALUE iter_data; + * rb_iterate(rb_each, recv, iter_func, iter_data); + * ``` + */ +VALUE rb_each(VALUE obj); + +/** + * Yields the block. In Ruby there is a concept called a block. You can pass + * one to a method. In a method, when called with a block, you can yield it + * using this function. + * + * ```CXX + * VALUE + * iterate(VALUE self) + * { + * extern int get_n(VALUE); + * extern VALUE get_v(VALUE, VALUE); + * const auto n = get_n(self); + * + * for (int i=0; i