ruby-changes:67712
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:00:48 +0900 (JST)
Subject: [ruby-changes:67712] 3341e178ef (master): include/ruby/internal/variable.h: add doxygen
https://git.ruby-lang.org/ruby.git/commit/?id=3341e178ef From 3341e178ef5729443729a0eaef42b305fc3aef1b 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: Thu, 14 Jan 2021 11:47:56 +0900 Subject: include/ruby/internal/variable.h: add doxygen Must not be a bad idea to improve documents. [ci skip] --- include/ruby/internal/variable.h | 296 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 285 insertions(+), 11 deletions(-) diff --git a/include/ruby/internal/variable.h b/include/ruby/internal/variable.h index a8ee860..1f84b92 100644 --- a/include/ruby/internal/variable.h +++ b/include/ruby/internal/variable.h @@ -18,45 +18,319 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/variable.h#L18 * Do not expect for instance `__VA_ARGS__` is always available. * We assume C99 for ruby itself but we don't assume languages of * extension libraries. They could be written in C++98. - * @brief C-function backended Ruby-global variables. + * @brief Declares rb_define_variable(). */ #include "ruby/internal/dllexport.h" #include "ruby/internal/value.h" +#include "ruby/internal/attr/nonnull.h" #include "ruby/internal/attr/noreturn.h" RBIMPL_SYMBOL_EXPORT_BEGIN() +/** + * Type that represents a global variable getter function. + * + * @param[in] id The variable name. + * @param[in,out] data Where the value is stored. + * @return The value that shall be visible from Ruby. + */ typedef VALUE rb_gvar_getter_t(ID id, VALUE *data); + +/** + * Type that represents a global variable setter function. + * + * @param[in] val The value to set. + * @param[in] id The variable name. + * @param[in,out] data Where the value is to be stored. + */ typedef void rb_gvar_setter_t(VALUE val, ID id, VALUE *data); + +/** + * Type that represents a global variable marker function. + * + * @param[in] var Where the value is to be stored. + */ typedef void rb_gvar_marker_t(VALUE *var); +/** + * @deprecated + * + * This function has no actual usage (than in ruby itself). Please ignore. It + * was a bad idea to expose this function to 3rd parties, but we can no longer + * delete it. + */ rb_gvar_getter_t rb_gvar_undef_getter; + +/** + * @deprecated + * + * This function has no actual usage (than in ruby itself). Please ignore. It + * was a bad idea to expose this function to 3rd parties, but we can no longer + * delete it. + */ rb_gvar_setter_t rb_gvar_undef_setter; + +/** + * @deprecated + * + * This function has no actual usage (than in ruby itself). Please ignore. It + * was a bad idea to expose this function to 3rd parties, but we can no longer + * delete it. + */ rb_gvar_marker_t rb_gvar_undef_marker; +/** + * This is the getter function that backs global variables defined from a ruby + * script. Extension libraries can use this if its global variable needs no + * custom logic. + */ rb_gvar_getter_t rb_gvar_val_getter; + +/** + * This is the setter function that backs global variables defined from a ruby + * script. Extension libraries can use this if its global variable needs no + * custom logic. + */ rb_gvar_setter_t rb_gvar_val_setter; + +/** + * This is the setter function that backs global variables defined from a ruby + * script. Extension libraries can use this if its global variable needs no + * custom logic. + */ rb_gvar_marker_t rb_gvar_val_marker; +/** + * @deprecated + * + * This function has no actual usage (than in ruby itself). Please ignore. It + * was a bad idea to expose this function to 3rd parties, but we can no longer + * delete it. + */ rb_gvar_getter_t rb_gvar_var_getter; + +/** + * @deprecated + * + * This function has no actual usage (than in ruby itself). Please ignore. It + * was a bad idea to expose this function to 3rd parties, but we can no longer + * delete it. + */ rb_gvar_setter_t rb_gvar_var_setter; + +/** + * @deprecated + * + * This function has no actual usage (than in ruby itself). Please ignore. It + * was a bad idea to expose this function to 3rd parties, but we can no longer + * delete it. + */ rb_gvar_marker_t rb_gvar_var_marker; RBIMPL_ATTR_NORETURN() +/** + * This function just raises ::rb_eNameError. Handy when you want to prohibit + * a global variable from being squashed by someone. + */ rb_gvar_setter_t rb_gvar_readonly_setter; -void rb_define_variable(const char*,VALUE*); -void rb_define_virtual_variable(const char*,rb_gvar_getter_t*,rb_gvar_setter_t*); -void rb_define_hooked_variable(const char*,VALUE*,rb_gvar_getter_t*,rb_gvar_setter_t*); -void rb_define_readonly_variable(const char*,const VALUE*); -void rb_define_const(VALUE,const char*,VALUE); -void rb_define_global_const(const char*,VALUE); +RBIMPL_ATTR_NONNULL(()) +/** + * "Shares" a global variable between Ruby and C. Normally a Ruby-level global + * variable is stored somewhere deep inside of the interpreter's execution + * context, but this way you can explicitly specify its storage. + * + * ```CXX + * static VALUE foo; + * + * extern "C" void + * init_Foo(void) + * { + * foo = rb_eval_string("..."); + * rb_define_global_variable("$foo", &foo); + * } + * ``` + * + * In the above example a Ruby global variable named `$foo` is stored in a C + * global variable named `foo`. + * + * @param[in] name Variable (Ruby side). + * @param[in] var Variable (C side). + * @post Ruby level global variable named `name` is defined if absent, + * and its storage is set to `var`. + */ +void rb_define_variable(const char *name, VALUE *var); + +RBIMPL_ATTR_NONNULL((1)) +/** + * Defines a global variable that is purely function-backended. By using this + * API a programmer can define a global variable that dynamically changes from + * time to time. + * + * @param[in] name Variable name, in C's string. + * @param[in] getter A getter function. + * @param[in] setter A setter function. + * @post Ruby level global variable named `name` is defined if absent. + * + * @internal + * + * @shyouhei doesn't know if this is an Easter egg or an official feature, but + * you can pass 0 to the third argument (setter). That effectively nullifies + * any efforts to write to the defining global variable. + */ +void rb_define_virtual_variable(const char *name, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter); + +RBIMPL_ATTR_NONNULL((1)) +/** + * Identical to rb_define_virtual_variable(), but can also specify a storage. + * A programmer can use the storage for e.g. memoisation, storing intermediate + * computation result, etc. + * + * Also you can pass 0 to this function, unlike other variants: + * + * - When getter is 0 ::rb_gvar_var_getter is used instead. + * - When setter is 0 ::rb_gvar_var_setter is used instead. + * - When data is 0, you must specify a non-zero setter function. Otherwise + * ::rb_gvar_var_setter tries to write to `*NULL`, and just causes SEGV. + * + * @param[in] name Variable name, in C's string. + * @param[in] var Variable storage. + * @param[in] getter A getter function. + * @param[in] setter A setter function. + * @post Ruby level global variable named `name` is defined if absent. + */ +void rb_define_hooked_variable(const char *name, VALUE *var, rb_gvar_getter_t *getter, rb_gvar_setter_t *setter); + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_define_variable(), except it does not allow Ruby programs to + * assign values to such global variable. C codes can still set values at + * will. This could be handy for you when implementing an `errno`-like + * experience, where a method updates a read-only global variable as a side- + * effect. + * + * @param[in] name Variable (Ruby side). + * @param[in] var Variable (C side). + * @post Ruby level global variable named `name` is defined if absent, + * and its storage is set to `var`. + */ +void rb_define_readonly_variable(const char *name, const VALUE *var); + +RBIMPL_ATTR_NONNULL(()) +/** + * Defines a Ruby level constant under a namespace. + * + * @param[out] klass Namespace for the constant to reside. + * @param[in] name Name of the constant. + * @param[in] val Value of the constant. + * @exception rb_eTypeError `klass` is not a kind of ::rb_cModule. + * @exception rb_eFrozenError `klass` is frozen. + * @post Ruby level constant `klass::name` is defined to be `val`. + * @note This API does not stop you from defining a constant that is + * unable to reach from ruby (like for instance passing + * non-capital letter to `name`). + * @note This API does not stop you from overwriting a constant that + * already exist. + * + * @internal + * + * Above description is in fact inaccurate. This API interfaces with Ractors. + */ +void rb_define_const(VALUE klass, const char *name, VALUE val); + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_define_const(), except it defines that of "global", + * i.e. toplevel constant. + * + * @param[in] name Name of the constant. + * @param[in] val Value of the constant. + * @exception rb_eFrozenError ::rb_cObject is frozen. + * @post Ruby level constant \::name is defined to be `val`. + * @note This API does not stop you from defining a constant that is + * unable to reach from ruby (like for instance passing + * non-capital letter to `name`). + * @note This API does not stop you from overwriting a constant that + * already exist. + */ +void rb_define_global_const(const char *name, VALUE val); + +RBIMPL_ATTR_NONNULL(()) +/** + * Asserts that the given constant is deprecated. Attempt to refer such + * constant will produce a warning. + * + * @param[in] mod Namespace of the target constant. + * @par (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/