ruby-changes:67727
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:01:05 +0900 (JST)
Subject: [ruby-changes:67727] 03fd22a170 (master): include/ruby/internal/iterator.h: add doxygen
https://git.ruby-lang.org/ruby.git/commit/?id=03fd22a170 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?= <shyouhei@r...> Date: Fri, 11 Dec 2020 18:26:27 +0900 Subject: 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 ef98d71..a2cd523 100644 --- a/eval.c +++ b/eval.c @@ -930,11 +930,6 @@ rb_jump_tag(int tag) https://github.com/ruby/ruby/blob/trunk/eval.c#L930 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) https://github.com/ruby/ruby/blob/trunk/eval.c#L951 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) https://github.com/ruby/ruby/blob/trunk/eval.c#L959 } } -/*! An equivalent of \c rescue clause. - * - * Equivalent to <code>begin .. rescue err_type .. end</code> - * - * \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, https://github.com/ruby/ruby/blob/trunk/eval.c#L970 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, https://github.com/ruby/ruby/blob/trunk/eval.c#L1030 return result; } -/*! An equivalent of \c rescue clause. - * - * Equivalent to <code>begin .. rescue .. end</code>. - * - * 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) https://github.com/ruby/ruby/blob/trunk/eval.c#L1076 return result; } -/*! - * An equivalent to \c ensure clause. - * - * Equivalent to <code>begin .. ensure .. end</code>. - * - * 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 70ac1bb..3512b0a 100644 --- a/include/ruby/internal/iterator.h +++ b/include/ruby/internal/iterator.h @@ -20,54 +20,488 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/iterator.h#L20 * 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<n; i++) { + * auto v = get_v(self, i); + * + * rb_yield(v); + * } + * return self; + * } + * ``` + * + * @param[in] val Passed to the block. + * @exception rb_eLocalJumpError There is no block given. + * @return Evaluated value of the given block. + */ +VALUE rb_yield(VALUE val); + +/** + * Identical to rb_yield(), except it takes variadic number of parameters and + * pass them to the block. + * + * @param[in] n Number of parameters. + * @param[in] ... List of arguments passed to the block. + * @exception rb_eLocalJumpError There is no block given. + * @return Evaluated value of the given block. + */ VALUE rb_yield_values(int n, ...); + +/** + * Identical to rb_yield_values(), except it takes the parameters as a C array + * instead of variadic arguments. + * + * @param[in] n Number of parameters. + * @param[in] argv List of arguments passed to the block. + * @exception rb_eLocalJumpError There is no block given. + * @return Evaluated value of the given block. + */ VALUE rb_yield_values2(int n, const VALUE *argv); + +/** + * Identical to rb_yield_values2(), except you can specify how to handle the + * last element of the given array. + * + * @param[in] n Number of parameters. + * @param[in] argv List of arguments passed to the block. + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `ary`'s last is not a keyword argument. + * - RB_PASS_KEYWORDS `ary`'s last is a keyword argument. + * - RB_PASS_CALLED_KEYWORDS makes no sense here. + * @exception rb_eLocalJumpError There is no block given. + * @return Evaluated value of the given block. + */ VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat); -VALUE rb_yield_splat(VALUE); -VALUE rb_yield_splat_kw(VALUE, int); + +/** + * Identical to rb_yield_values(), except it splats an array to generate the + * list of parameters. + * + * @param[in] ary Array to splat. + * @exception rb_eLocalJumpError There is no block given. + * @return Evaluated value of the given block. + */ +VALUE rb_yield_splat(VALUE ary); + +/** + * Identical to rb_yield_splat(), except you can specify how to handle the last + * element of the given array. + * + * @param[in] ary Array to splat. + * @param[in] kw_splat Handling of keyword parameters: + * - RB_NO_KEYWORDS `ary`'s last is not a keyword argument. + (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/