15#include "ruby/internal/config.h"
24#include "internal/class.h"
25#include "internal/enumerator.h"
26#include "internal/error.h"
27#include "internal/hash.h"
28#include "internal/imemo.h"
29#include "internal/numeric.h"
30#include "internal/range.h"
31#include "internal/rational.h"
32#include "internal/set.h"
180static VALUE rb_cLazy;
181static ID id_rewind, id_to_enum, id_each_entry;
182static ID id_next, id_result, id_receiver, id_arguments, id_memo, id_method, id_force;
183static VALUE sym_each, sym_yield;
185static VALUE lazy_use_super_method;
187extern ID ruby_static_id_cause;
189#define id_call idCall
190#define id_cause ruby_static_id_cause
191#define id_each idEach
193#define id_initialize idInitialize
194#define id_size idSize
213RUBY_REFERENCES(enumerator_refs) = {
226static VALUE rb_cGenerator, rb_cYielder, rb_cEnumProducer;
247 lazyenum_proc_func *proc;
248 lazyenum_size_func *size;
249 lazyenum_precheck_func *precheck;
261static VALUE rb_cEnumChain;
268static VALUE rb_cEnumProduct;
279 RUBY_REFS_LIST_PTR(enumerator_refs),
284 0, NULL, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE
288enumerator_ptr(
VALUE obj)
293 if (!ptr || UNDEF_P(ptr->obj)) {
294 rb_raise(rb_eArgError,
"uninitialized enumerator");
300proc_entry_mark_and_move(
void *p)
303 rb_gc_mark_and_move(&ptr->proc);
304 rb_gc_mark_and_move(&ptr->memo);
310 proc_entry_mark_and_move,
313 proc_entry_mark_and_move,
315 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
398 enumerator = rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
406enumerator_allocate(
VALUE klass)
422 rb_check_frozen(enum_obj);
426 rb_raise(rb_eArgError,
"unallocated enumerator");
438 ptr->size_fn = size_fn;
439 ptr->kw_splat = kw_splat;
445convert_to_feasible_size_value(
VALUE obj)
490enumerator_initialize(
int argc,
VALUE *argv,
VALUE obj)
493 VALUE recv = generator_init(generator_allocate(rb_cGenerator), iter);
495 VALUE size = convert_to_feasible_size_value(arg0);
497 return enumerator_init(obj, recv, sym_each, 0, 0, 0, size,
false);
507 ptr0 = enumerator_ptr(orig);
516 rb_raise(rb_eArgError,
"unallocated enumerator");
520 ptr1->meth = ptr0->meth;
526 ptr1->size_fn = ptr0->size_fn;
537 return rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
541static int lazy_precheck(
VALUE procs);
549 base_class = rb_cLazy;
552 obj = enumerator_init(enumerator_allocate(
rb_cEnumerator), obj, sym_each, 0, 0, 0,
Qnil,
false);
555 return enumerator_init(enumerator_allocate(base_class),
556 obj, meth, argc, argv, size_fn,
Qnil, kw_splat);
562 return rb_enumeratorize_with_size_kw(obj, meth, argc, argv, size_fn,
rb_keyword_given_p());
569 const VALUE *argv = 0;
570 const struct enumerator *e = enumerator_ptr(obj);
573 VALUE args = e->args;
623enumerator_each(
int argc,
VALUE *argv,
VALUE obj)
630#if SIZEOF_INT < SIZEOF_LONG
646 if (!lazy_precheck(e->procs))
return Qnil;
648 return enumerator_block_call(obj, 0, obj);
654 struct MEMO *memo = (
struct MEMO *)m;
655 VALUE idx = memo->v1;
656 MEMO_V1_SET(memo, rb_int_succ(idx));
665enumerator_size(
VALUE obj);
670 return enumerator_size(obj);
686enumerator_with_index(
int argc,
VALUE *argv,
VALUE obj)
693 return enumerator_block_call(obj, enumerator_with_index_i, (
VALUE)rb_imemo_memo_new(memo, 0, 0));
707enumerator_each_with_index(
VALUE obj)
709 return enumerator_with_index(0, NULL, obj);
754 enumerator_block_call(obj, enumerator_with_object_i, memo);
765 rb_fiber_yield(1, &args);
766 if (!UNDEF_P(e->feedvalue)) {
767 feedvalue = e->feedvalue;
783 return rb_fiber_yield(1, &nil);
789 VALUE curr = rb_fiber_current();
801 VALUE exc = e->stop_exc;
802 VALUE result = rb_attr_get(exc, id_result);
803 VALUE mesg = rb_attr_get(exc, idMesg);
811 curr = rb_fiber_current();
813 if (!e->fib || !rb_fiber_alive_p(e->fib)) {
817 vs = rb_fiber_resume(e->fib, 1, &curr);
874enumerator_next_values(
VALUE obj)
879 rb_check_frozen(obj);
881 if (!UNDEF_P(e->lookahead)) {
887 return get_next_values(obj, e);
891ary2sv(
VALUE args,
int dup)
931enumerator_next(
VALUE obj)
933 VALUE vs = enumerator_next_values(obj);
934 return ary2sv(vs, 0);
938enumerator_peek_values(
VALUE obj)
942 rb_check_frozen(obj);
944 if (UNDEF_P(e->lookahead)) {
945 RB_OBJ_WRITE(obj, &e->lookahead, get_next_values(obj, e));
982enumerator_peek_values_m(
VALUE obj)
984 return rb_ary_dup(enumerator_peek_values(obj));
1012enumerator_peek(
VALUE obj)
1014 VALUE vs = enumerator_peek_values(obj);
1015 return ary2sv(vs, 1);
1069 rb_check_frozen(obj);
1071 if (!UNDEF_P(e->feedvalue)) {
1089enumerator_rewind(
VALUE obj)
1093 rb_check_frozen(obj);
1110inspect_enumerator(
VALUE obj,
VALUE dummy,
int recur)
1113 VALUE eobj, str, cname;
1119 if (!e || UNDEF_P(e->obj)) {
1120 return rb_sprintf(
"#<%"PRIsVALUE
": uninitialized>",
rb_class_path(cname));
1124 str = rb_sprintf(
"#<%"PRIsVALUE
": ...>",
rb_class_path(cname));
1131 eobj = generator_ptr(e->obj)->obj;
1137 str = rb_sprintf(
"#<%"PRIsVALUE
": %+"PRIsVALUE
">",
rb_class_path(cname), eobj);
1140 str = rb_sprintf(
"#<%"PRIsVALUE
": %"PRIsVALUE, cname, str);
1141 append_method(
RARRAY_AREF(e->procs, i), str, e->meth, e->args);
1147 eobj = rb_attr_get(obj, id_receiver);
1153 str = rb_sprintf(
"#<%"PRIsVALUE
": %+"PRIsVALUE,
rb_class_path(cname), eobj);
1154 append_method(obj, str, e->meth, e->args);
1164 if (
SYMBOL_P(key))
return ST_CONTINUE;
1165 *(
int *)arg = FALSE;
1173 rb_str_catf(str,
"% "PRIsVALUE
": %"PRIsVALUE
", ", key, val);
1182 method = rb_attr_get(obj, id_method);
1184 if (!
NIL_P(method)) {
1189 method = rb_id2str(default_method);
1194 return append_method_args(obj, str, default_args);
1202 eargs = rb_attr_get(obj, id_arguments);
1204 eargs = default_args;
1218 if (all_key) kwds = argv[--argc];
1222 VALUE arg = *argv++;
1247enumerator_inspect(
VALUE obj)
1282enumerator_size(
VALUE obj)
1286 const VALUE *argv = NULL;
1290 struct generator *g = generator_ptr(e->obj);
1296 struct proc_entry *entry = proc_entry_ptr(proc);
1297 lazyenum_size_func *size_fn = entry->fn->size;
1301 receiver = (*size_fn)(proc, receiver);
1307 return (*e->size_fn)(e->obj, e->args, obj);
1314 if (!UNDEF_P(size))
return size;
1322yielder_mark_and_move(
void *p)
1325 rb_gc_mark_and_move(&ptr->proc);
1331 yielder_mark_and_move,
1334 yielder_mark_and_move,
1336 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
1340yielder_ptr(
VALUE obj)
1345 if (!ptr || UNDEF_P(ptr->proc)) {
1346 rb_raise(rb_eArgError,
"uninitialized yielder");
1353yielder_allocate(
VALUE klass)
1372 rb_raise(rb_eArgError,
"unallocated yielder");
1382yielder_initialize(
VALUE obj)
1393 struct yielder *ptr = yielder_ptr(obj);
1402 struct yielder *ptr = yielder_ptr(obj);
1422yielder_to_proc(
VALUE obj)
1438 return yielder_init(yielder_allocate(rb_cYielder),
rb_proc_new(yielder_yield_i, 0));
1445generator_mark_and_move(
void *p)
1448 rb_gc_mark_and_move(&ptr->proc);
1449 rb_gc_mark_and_move(&ptr->obj);
1455 generator_mark_and_move,
1458 generator_mark_and_move,
1460 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
1464generator_ptr(
VALUE obj)
1469 if (!ptr || UNDEF_P(ptr->proc)) {
1470 rb_raise(rb_eArgError,
"uninitialized generator");
1477generator_allocate(
VALUE klass)
1493 rb_check_frozen(obj);
1497 rb_raise(rb_eArgError,
"unallocated generator");
1507generator_initialize(
int argc,
VALUE *argv,
VALUE obj)
1521 "wrong argument type %"PRIsVALUE
" (expected Proc)",
1525 rb_warn(
"given block not used");
1529 return generator_init(obj, proc);
1540 ptr0 = generator_ptr(orig);
1545 rb_raise(rb_eArgError,
"unallocated generator");
1555generator_each(
int argc,
VALUE *argv,
VALUE obj)
1557 struct generator *ptr = generator_ptr(obj);
1570enum_size(
VALUE self)
1573 return UNDEF_P(r) ?
Qnil : r;
1579 return enum_size(self);
1582#define lazy_receiver_size lazy_map_size
1613 rb_block_call(m, id_each, argc-1, argv+1, lazy_init_iterator, val);
1617#define memo_value v2
1618#define memo_flags u3.state
1619#define LAZY_MEMO_BREAK 1
1620#define LAZY_MEMO_PACKED 2
1621#define LAZY_MEMO_BREAK_P(memo) ((memo)->memo_flags & LAZY_MEMO_BREAK)
1622#define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED)
1623#define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK)
1624#define LAZY_MEMO_RESET_BREAK(memo) ((memo)->memo_flags &= ~LAZY_MEMO_BREAK)
1625#define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value)
1626#define LAZY_MEMO_SET_PACKED(memo) ((memo)->memo_flags |= LAZY_MEMO_PACKED)
1627#define LAZY_MEMO_RESET_PACKED(memo) ((memo)->memo_flags &= ~LAZY_MEMO_PACKED)
1629#define LAZY_NEED_BLOCK(func) \
1630 if (!rb_block_given_p()) { \
1631 rb_raise(rb_eArgError, "tried to call lazy " #func " without a block"); \
1642 struct MEMO *result;
1644 result = rb_imemo_memo_new(m, rb_enum_values_pack(argc, argv),
1645 argc > 1 ? LAZY_MEMO_PACKED : 0);
1646 return lazy_yielder_result(result,
yielder, procs_array, memos, 0);
1650lazy_yielder_yield(
struct MEMO *result,
long memo_index,
int argc,
const VALUE *argv)
1652 VALUE m = result->v1;
1656 LAZY_MEMO_SET_VALUE(result, rb_enum_values_pack(argc, argv));
1658 LAZY_MEMO_SET_PACKED(result);
1660 LAZY_MEMO_RESET_PACKED(result);
1661 return lazy_yielder_result(result,
yielder, procs_array, memos, memo_index);
1671 struct proc_entry *entry = proc_entry_ptr(proc);
1672 if (!(*entry->fn->proc)(proc, result, memos, i)) {
1681 if (LAZY_MEMO_BREAK_P(result)) {
1684 return result->memo_value;
1707 struct generator *old_gen_ptr = generator_ptr(e->obj);
1708 obj = old_gen_ptr->obj;
1714 generator = generator_allocate(rb_cGenerator);
1726lazy_precheck(
VALUE procs)
1729 long num_procs =
RARRAY_LEN(procs), i = num_procs;
1732 struct proc_entry *entry = proc_entry_ptr(proc);
1733 lazyenum_precheck_func *precheck = entry->fn->precheck;
1734 if (precheck && !precheck(proc))
return FALSE;
1831lazy_initialize(
int argc,
VALUE *argv,
VALUE self)
1837 LAZY_NEED_BLOCK(
new);
1842 generator = generator_allocate(rb_cGenerator);
1844 enumerator_init(self,
generator, sym_each, 0, 0, 0, size, 0);
1860lazy_to_a(
VALUE self)
1868 ID id = rb_frame_this_func();
1884 lazy_set_args(lazy, args);
1885 e->size_fn = size_fn;
1896 VALUE new_generator;
1901 &proc_entry_data_type, entry);
1908 lazy_set_args(entry_obj, memo);
1911 new_generator = lazy_generator_init(obj, new_procs);
1914 new_obj = enumerator_init_copy(enumerator_allocate(rb_cLazy), obj);
1915 new_e = RTYPEDDATA_GET_DATA(new_obj);
1924 new_e->meth = id_each;
1962enumerable_lazy(
VALUE obj)
1973 return enumerator_init(enumerator_allocate(rb_cLazy),
1974 obj, meth, argc, argv, size_fn,
Qnil, kw_splat);
2001lazy_to_enum(
int argc,
VALUE *argv,
VALUE self)
2003 VALUE lazy, meth = sym_each, super_meth;
2009 if (
RTEST((super_meth = rb_hash_aref(lazy_use_super_method, meth)))) {
2022 return enum_size(self);
2033lazy_eager(
VALUE self)
2036 self, sym_each, 0, 0, lazy_eager_size,
Qnil, 0);
2051 const VALUE *argv = &result->memo_value;
2052 if (LAZY_MEMO_PACKED_P(result)) {
2053 const VALUE args = *argv;
2064 LAZY_MEMO_SET_VALUE(result, value);
2065 LAZY_MEMO_RESET_PACKED(result);
2076 lazy_map_proc, lazy_map_size,
2095 LAZY_NEED_BLOCK(map);
2096 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_map_funcs);
2100 struct MEMO *result;
2109 return lazy_yielder_yield(arg->result, arg->index, argc, argv);
2117 const long proc_index = memo_index + 1;
2118 int break_p = LAZY_MEMO_BREAK_P(result);
2124 struct flat_map_i_arg arg = {.result = result, .index = proc_index};
2125 LAZY_MEMO_RESET_BREAK(result);
2127 if (break_p) LAZY_MEMO_SET_BREAK(result);
2133 LAZY_MEMO_RESET_BREAK(result);
2136 lazy_yielder_yield(result, proc_index, 1, &argv);
2138 if (break_p) LAZY_MEMO_SET_BREAK(result);
2142 LAZY_MEMO_SET_VALUE(result, value);
2143 LAZY_MEMO_RESET_PACKED(result);
2148 lazy_flat_map_proc, 0,
2175lazy_flat_map(
VALUE obj)
2177 LAZY_NEED_BLOCK(flat_map);
2178 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_flat_map_funcs);
2185 if (!
RTEST(chain))
return 0;
2190 lazy_select_proc, 0,
2202lazy_select(
VALUE obj)
2204 LAZY_NEED_BLOCK(select);
2205 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_select_funcs);
2212 if (!
RTEST(value))
return 0;
2213 LAZY_MEMO_SET_VALUE(result, value);
2214 LAZY_MEMO_RESET_PACKED(result);
2219 lazy_filter_map_proc, 0,
2233lazy_filter_map(
VALUE obj)
2235 LAZY_NEED_BLOCK(filter_map);
2236 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_filter_map_funcs);
2243 if (
RTEST(chain))
return 0;
2248 lazy_reject_proc, 0,
2259lazy_reject(
VALUE obj)
2261 LAZY_NEED_BLOCK(reject);
2262 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_reject_funcs);
2270 if (!
RTEST(chain))
return 0;
2278 VALUE value, chain =
rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2280 if (!
RTEST(chain))
return 0;
2282 LAZY_MEMO_SET_VALUE(result, value);
2283 LAZY_MEMO_RESET_PACKED(result);
2289 lazy_grep_iter_proc, 0,
2308 &lazy_grep_iter_funcs : &lazy_grep_funcs;
2309 return lazy_add_method(obj, 0, 0, pattern,
rb_ary_new3(1, pattern), funcs);
2317 if (
RTEST(chain))
return 0;
2325 VALUE value, chain =
rb_funcall(entry->memo, id_eqq, 1, result->memo_value);
2327 if (
RTEST(chain))
return 0;
2329 LAZY_MEMO_SET_VALUE(result, value);
2330 LAZY_MEMO_RESET_PACKED(result);
2336 lazy_grep_v_iter_proc, 0,
2340 lazy_grep_v_proc, 0,
2355 &lazy_grep_v_iter_funcs : &lazy_grep_v_funcs;
2356 return lazy_add_method(obj, 0, 0, pattern,
rb_ary_new3(1, pattern), funcs);
2375 VALUE ary, arrays = entry->memo;
2384 LAZY_MEMO_SET_VALUE(result, ary);
2394 VALUE zip_args = entry->memo;
2413 LAZY_MEMO_SET_VALUE(result, ary);
2418 {lazy_zip_func, lazy_receiver_size,},
2419 {lazy_zip_arrays_func, lazy_receiver_size,},
2442 for (i = 0; i < argc; i++) {
2445 for (; i < argc; i++) {
2447 rb_raise(
rb_eTypeError,
"wrong argument type %"PRIsVALUE
" (must respond to :each)",
2452 funcs = &lazy_zip_funcs[0];
2458 return lazy_add_method(obj, 0, 0, ary, ary, funcs);
2473 if (--remain == 0) LAZY_MEMO_SET_BREAK(result);
2491 return entry->memo !=
INT2FIX(0);
2495 lazy_take_proc, lazy_take_size, lazy_take_precheck,
2511 rb_raise(rb_eArgError,
"attempt to take negative size");
2516 return lazy_add_method(obj, 0, 0, n,
rb_ary_new3(1, n), &lazy_take_funcs);
2524 LAZY_MEMO_SET_BREAK(result);
2531 lazy_take_while_proc, 0,
2542lazy_take_while(
VALUE obj)
2544 LAZY_NEED_BLOCK(take_while);
2545 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_take_while_funcs);
2552 if (
NIL_P(receiver))
2582 lazy_drop_proc, lazy_drop_size,
2601 rb_raise(rb_eArgError,
"attempt to drop negative size");
2604 return lazy_add_method(obj, 2, argv, n,
rb_ary_new3(1, n), &lazy_drop_funcs);
2619 if (
RTEST(drop))
return 0;
2626 lazy_drop_while_proc, 0,
2637lazy_drop_while(
VALUE obj)
2639 LAZY_NEED_BLOCK(drop_while);
2640 return lazy_add_method(obj, 0, 0,
Qfalse,
Qnil, &lazy_drop_while_funcs);
2644lazy_uniq_check(
VALUE chain,
VALUE memos,
long memo_index)
2653 return !rb_set_add_no_check(set, chain);
2659 if (lazy_uniq_check(result->memo_value, memos, memo_index))
return 0;
2668 if (lazy_uniq_check(chain, memos, memo_index))
return 0;
2673 lazy_uniq_iter_proc, 0,
2693 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, funcs);
2699 if (
NIL_P(result->memo_value))
return 0;
2704 lazy_compact_proc, 0,
2715lazy_compact(
VALUE obj)
2717 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_compact_funcs);
2731 argv[0] = result->memo_value;
2735 LAZY_MEMO_RESET_PACKED(result);
2739 LAZY_MEMO_SET_PACKED(result);
2746lazy_with_index_size(
VALUE proc,
VALUE receiver)
2752 lazy_with_index_proc, lazy_with_index_size,
2773lazy_with_index(
int argc,
VALUE *argv,
VALUE obj)
2795 lazy_tap_each_proc, 0,
2820lazy_tap_each(
VALUE obj)
2824 rb_raise(rb_eArgError,
"tried to call lazy tap_each without a block");
2827 return lazy_add_method(obj, 0, 0,
Qnil,
Qnil, &lazy_tap_each_funcs);
2839lazy_chunk(
VALUE self)
2850lazy_chunk_while(
VALUE self)
2862lazy_slice_after(
VALUE self)
2874lazy_slice_before(
VALUE self)
2885lazy_slice_when(
VALUE self)
2957stop_result(
VALUE self)
2959 return rb_attr_get(self, id_result);
2967producer_mark_and_move(
void *p)
2970 rb_gc_mark_and_move(&ptr->init);
2971 rb_gc_mark_and_move(&ptr->proc);
2972 rb_gc_mark_and_move(&ptr->size);
2975#define producer_free RUBY_TYPED_DEFAULT_FREE
2978producer_memsize(
const void *p)
2986 producer_mark_and_move,
2989 producer_mark_and_move,
2991 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE
2995producer_ptr(
VALUE obj)
3000 if (!ptr || UNDEF_P(ptr->proc)) {
3001 rb_raise(rb_eArgError,
"uninitialized producer");
3008producer_allocate(
VALUE klass)
3029 rb_raise(rb_eArgError,
"unallocated producer");
3042 return rb_attr_get(exc, id_result);
3045NORETURN(
static VALUE producer_each_i(
VALUE obj));
3048producer_each_i(
VALUE obj)
3051 VALUE init, proc, curr;
3053 ptr = producer_ptr(obj);
3057 if (UNDEF_P(init)) {
3075producer_each(
VALUE obj)
3085 struct producer *ptr = producer_ptr(obj);
3086 VALUE size = ptr->size;
3154enumerator_s_produce(
int argc,
VALUE *argv,
VALUE klass)
3161 keyword_ids[0] = rb_intern(
"size");
3165 size = UNDEF_P(size) ?
DBL2NUM(HUGE_VAL) : convert_to_feasible_size_value(size);
3167 if (argc == 0 || (argc == 1 && !
NIL_P(opts))) {
3187enum_chain_mark_and_move(
void *p)
3190 rb_gc_mark_and_move(&ptr->enums);
3193#define enum_chain_free RUBY_TYPED_DEFAULT_FREE
3196enum_chain_memsize(
const void *p)
3204 enum_chain_mark_and_move,
3207 enum_chain_mark_and_move,
3209 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED
3213enum_chain_ptr(
VALUE obj)
3218 if (!ptr || UNDEF_P(ptr->enums)) {
3219 rb_raise(rb_eArgError,
"uninitialized chain");
3226enum_chain_allocate(
VALUE klass)
3254 rb_check_frozen(obj);
3257 if (!ptr) rb_raise(rb_eArgError,
"unallocated chain");
3266new_enum_chain(
VALUE enums)
3269 VALUE obj = enum_chain_initialize(enum_chain_allocate(rb_cEnumChain), enums);
3273 return enumerable_lazy(obj);
3287 ptr0 = enum_chain_ptr(orig);
3291 if (!ptr1) rb_raise(rb_eArgError,
"unallocated chain");
3294 ptr1->pos = ptr0->pos;
3300enum_chain_total_size(
VALUE enums)
3331enum_chain_size(
VALUE obj)
3333 return enum_chain_total_size(enum_chain_ptr(obj)->enums);
3339 return enum_chain_size(obj);
3361enum_chain_each(
int argc,
VALUE *argv,
VALUE obj)
3369 objptr = enum_chain_ptr(obj);
3370 enums = objptr->enums;
3390enum_chain_rewind(
VALUE obj)
3392 struct enum_chain *objptr = enum_chain_ptr(obj);
3393 VALUE enums = objptr->enums;
3396 for (i = objptr->pos; 0 <= i && i <
RARRAY_LEN(enums); objptr->pos = --i) {
3404inspect_enum_chain(
VALUE obj,
VALUE dummy,
int recur)
3411 if (!ptr || UNDEF_P(ptr->enums)) {
3412 return rb_sprintf(
"#<%"PRIsVALUE
": uninitialized>",
rb_class_path(klass));
3416 return rb_sprintf(
"#<%"PRIsVALUE
": ...>",
rb_class_path(klass));
3419 return rb_sprintf(
"#<%"PRIsVALUE
": %+"PRIsVALUE
">",
rb_class_path(klass), ptr->enums);
3429enum_chain_inspect(
VALUE obj)
3449 return new_enum_chain(enums);
3465 return new_enum_chain(rb_ary_new_from_args(2, obj, eobj));
3502enum_product_mark_and_move(
void *p)
3505 rb_gc_mark_and_move(&ptr->enums);
3508#define enum_product_free RUBY_TYPED_DEFAULT_FREE
3511enum_product_memsize(
const void *p)
3519 enum_product_mark_and_move,
3521 enum_product_memsize,
3522 enum_product_mark_and_move,
3524 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED
3528enum_product_ptr(
VALUE obj)
3533 if (!ptr || UNDEF_P(ptr->enums)) {
3534 rb_raise(rb_eArgError,
"uninitialized product");
3541enum_product_allocate(
VALUE klass)
3564enum_product_initialize(
int argc,
VALUE *argv,
VALUE obj)
3572 rb_exc_raise(rb_keyword_error_new(
"unknown", rb_hash_keys(options)));
3575 rb_check_frozen(obj);
3578 if (!ptr) rb_raise(rb_eArgError,
"unallocated product");
3592 ptr0 = enum_product_ptr(orig);
3596 if (!ptr1) rb_raise(rb_eArgError,
"unallocated product");
3604enum_product_total_size(
VALUE enums)
3644enum_product_size(
VALUE obj)
3646 return enum_product_total_size(enum_product_ptr(obj)->enums);
3652 return enum_product_size(obj);
3669 pstate->argv[pstate->index++] = value;
3671 VALUE val = product_each(pstate->obj, pstate);
3680 VALUE enums = ptr->enums;
3682 if (pstate->index < pstate->argc) {
3713 VALUE ret = product_each(obj, &state);
3731enum_product_each(
VALUE obj)
3747enum_product_rewind(
VALUE obj)
3750 VALUE enums = ptr->enums;
3761inspect_enum_product(
VALUE obj,
VALUE dummy,
int recur)
3768 if (!ptr || UNDEF_P(ptr->enums)) {
3769 return rb_sprintf(
"#<%"PRIsVALUE
": uninitialized>",
rb_class_path(klass));
3773 return rb_sprintf(
"#<%"PRIsVALUE
": ...>",
rb_class_path(klass));
3776 return rb_sprintf(
"#<%"PRIsVALUE
": %+"PRIsVALUE
">",
rb_class_path(klass), ptr->enums);
3786enum_product_inspect(
VALUE obj)
3808enumerator_s_product(
int argc,
VALUE *argv,
VALUE klass)
3812 rb_scan_args(argc, argv,
"*:&", &enums, &options, &block);
3815 rb_exc_raise(rb_keyword_error_new(
"unknown", rb_hash_keys(options)));
3818 VALUE obj = enum_product_initialize(argc, argv, enum_product_allocate(rb_cEnumProduct));
3820 if (!
NIL_P(block)) {
3821 enum_product_run(obj, block);
3836RUBY_REFERENCES(arith_seq_refs) = {
3854 "arithmetic_sequence",
3856 RUBY_REFS_LIST_PTR(arith_seq_refs),
3861 .parent = &enumerator_data_type,
3862 .
flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE
3866arith_seq_allocate(
VALUE klass)
3872 ptr->enumerator.obj =
Qundef;
3894 VALUE aseq = enumerator_init(arith_seq_allocate(rb_cArithSeq),
3902 ptr->exclude_end = excl;
3914arith_seq_begin(
VALUE self)
3927arith_seq_end(
VALUE self)
3941arith_seq_step(
VALUE self)
3954arith_seq_exclude_end(
VALUE self)
3958 return RBOOL(ptr->exclude_end);
3962arith_seq_exclude_end_p(
VALUE self)
3966 return ptr->exclude_end;
3973 component->
begin = arith_seq_begin(obj);
3974 component->
end = arith_seq_end(obj);
3975 component->
step = arith_seq_step(obj);
3976 component->
exclude_end = arith_seq_exclude_end_p(obj);
3988rb_arithmetic_sequence_beg_len_step(
VALUE obj,
long *begp,
long *lenp,
long *stepp,
long len,
int err)
3990 RBIMPL_NONNULL_ARG(begp);
3991 RBIMPL_NONNULL_ARG(lenp);
3992 RBIMPL_NONNULL_ARG(stepp);
3995 if (!rb_arithmetic_sequence_extract(obj, &aseq)) {
4015 if (err == 0 && (step < -1 || step > 1)) {
4042 rb_raise(rb_eArgError,
"attempt to take negative size");
4048 b = arith_seq_begin(self);
4049 e = arith_seq_end(self);
4050 s = arith_seq_step(self);
4051 x = arith_seq_exclude_end_p(self);
4065 b = rb_big_plus(b, s);
4083 while (n > 0 && i < end) {
4085 if (i > LONG_MAX - unit)
break;
4096 while (n > 0 && i > end) {
4098 if (i < LONG_MIN - unit)
break;
4110 double end =
NIL_P(e) ? (unit < 0 ? -1 : 1)*HUGE_VAL :
NUM2DBL(e);
4111 double len = ruby_float_step_size(beg, end, unit, x);
4126 else if (unit == 0) {
4129 for (i = 0; i <
len; ++i) {
4135 for (i = 0; i < n; ++i) {
4136 double d = i*unit+beg;
4137 if (unit >= 0 ? end < d : d < end) d = end;
4161arith_seq_first(
int argc,
VALUE *argv,
VALUE self)
4167 b = arith_seq_begin(self);
4168 e = arith_seq_end(self);
4169 s = arith_seq_step(self);
4187 return arith_seq_take(self, argv[0]);
4194 return rb_int_plus(a, b);
4197 return rb_float_plus(a, b);
4200 return rb_rational_plus(a, b);
4211 return rb_int_minus(a, b);
4214 return rb_float_minus(a, b);
4217 return rb_rational_minus(a, b);
4228 return rb_int_mul(a, b);
4231 return rb_float_mul(a, b);
4234 return rb_rational_mul(a, b);
4246 q = rb_int_idiv(a, b);
4249 q = rb_float_div(a, b);
4252 q = rb_rational_div(a, b);
4262 return rb_float_floor(q, 0);
4265 return rb_rational_floor(q, 0);
4281arith_seq_last(
int argc,
VALUE *argv,
VALUE self)
4283 VALUE b, e, s, len_1,
len, last, nv, ary;
4284 int last_is_adjusted;
4287 e = arith_seq_end(self);
4290 "cannot get the last element of endless arithmetic sequence");
4293 b = arith_seq_begin(self);
4294 s = arith_seq_step(self);
4296 len_1 = num_idiv(num_minus(e, b), s);
4297 if (rb_num_negative_int_p(len_1)) {
4304 last = num_plus(b, num_mul(s, len_1));
4305 if ((last_is_adjusted = arith_seq_exclude_end_p(self) &&
rb_equal(last, e))) {
4306 last = num_minus(last, s);
4313 if (last_is_adjusted) {
4329 rb_raise(rb_eArgError,
"negative array size");
4333 b = rb_int_minus(last, rb_int_mul(s, nv));
4335 b = rb_int_plus(b, s);
4350arith_seq_inspect(
VALUE self)
4358 eobj = rb_attr_get(self, id_receiver);
4364 str = rb_sprintf(
"(%s%"PRIsVALUE
"%s.", range_p ?
"(" :
"", eobj, range_p ?
")" :
"");
4367 append_method_args(eobj, str, e->args);
4388 if (!
rb_equal(arith_seq_begin(self), arith_seq_begin(other))) {
4392 if (!
rb_equal(arith_seq_end(self), arith_seq_end(other))) {
4396 if (!
rb_equal(arith_seq_step(self), arith_seq_step(other))) {
4400 if (arith_seq_exclude_end_p(self) != arith_seq_exclude_end_p(other)) {
4418arith_seq_hash(
VALUE self)
4424 v = rb_hash(arith_seq_begin(self));
4426 v = rb_hash(arith_seq_end(self));
4428 v = rb_hash(arith_seq_step(self));
4435#define NUM_GE(x, y) RTEST(rb_num_coerce_relop((x), (y), idGE))
4450arith_seq_each(
VALUE self)
4452 VALUE c, e, s, len_1, last;
4457 c = arith_seq_begin(self);
4458 e = arith_seq_end(self);
4459 s = arith_seq_step(self);
4460 x = arith_seq_exclude_end_p(self);
4469 c = rb_int_plus(c, s);
4483 len_1 = num_idiv(num_minus(e, c), s);
4484 last = num_plus(c, num_mul(s, len_1));
4486 last = num_minus(last, s);
4489 if (rb_num_negative_int_p(s)) {
4490 while (NUM_GE(c, last)) {
4496 while (NUM_GE(last, c)) {
4513arith_seq_size(
VALUE self)
4518 b = arith_seq_begin(self);
4519 e = arith_seq_end(self);
4520 s = arith_seq_step(self);
4521 x = arith_seq_exclude_end_p(self);
4527 if (rb_num_negative_int_p(s)) {
4539 if (isinf(n))
return DBL2NUM(n);
4541 return rb_dbl2big(n);
4556 len_1 = rb_int_idiv(rb_int_minus(e, b), s);
4557 if (rb_num_negative_int_p(len_1)) {
4561 last = rb_int_plus(b, rb_int_mul(s, len_1));
4572#define sym(name) ID2SYM(rb_intern_const(name))
4574InitVM_Enumerator(
void)
4610 rb_define_alias(rb_cLazy,
"_enumerable_collect_concat",
"collect_concat");
4626 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_map"));
4627 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_collect"));
4628 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_flat_map"));
4629 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_collect_concat"));
4630 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_select"));
4631 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_find_all"));
4632 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_filter"));
4633 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_filter_map"));
4634 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_reject"));
4635 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_grep"));
4636 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_grep_v"));
4637 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_zip"));
4638 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_take"));
4639 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_take_while"));
4640 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_drop"));
4641 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_drop_while"));
4642 rb_funcall(rb_cLazy, id_private, 1, sym(
"_enumerable_uniq"));
4675 lazy_use_super_method = rb_hash_new_capa(18);
4676 rb_hash_aset(lazy_use_super_method, sym(
"map"), sym(
"_enumerable_map"));
4677 rb_hash_aset(lazy_use_super_method, sym(
"collect"), sym(
"_enumerable_collect"));
4678 rb_hash_aset(lazy_use_super_method, sym(
"flat_map"), sym(
"_enumerable_flat_map"));
4679 rb_hash_aset(lazy_use_super_method, sym(
"collect_concat"), sym(
"_enumerable_collect_concat"));
4680 rb_hash_aset(lazy_use_super_method, sym(
"select"), sym(
"_enumerable_select"));
4681 rb_hash_aset(lazy_use_super_method, sym(
"find_all"), sym(
"_enumerable_find_all"));
4682 rb_hash_aset(lazy_use_super_method, sym(
"filter"), sym(
"_enumerable_filter"));
4683 rb_hash_aset(lazy_use_super_method, sym(
"filter_map"), sym(
"_enumerable_filter_map"));
4684 rb_hash_aset(lazy_use_super_method, sym(
"reject"), sym(
"_enumerable_reject"));
4685 rb_hash_aset(lazy_use_super_method, sym(
"grep"), sym(
"_enumerable_grep"));
4686 rb_hash_aset(lazy_use_super_method, sym(
"grep_v"), sym(
"_enumerable_grep_v"));
4687 rb_hash_aset(lazy_use_super_method, sym(
"zip"), sym(
"_enumerable_zip"));
4688 rb_hash_aset(lazy_use_super_method, sym(
"take"), sym(
"_enumerable_take"));
4689 rb_hash_aset(lazy_use_super_method, sym(
"take_while"), sym(
"_enumerable_take_while"));
4690 rb_hash_aset(lazy_use_super_method, sym(
"drop"), sym(
"_enumerable_drop"));
4691 rb_hash_aset(lazy_use_super_method, sym(
"drop_while"), sym(
"_enumerable_drop_while"));
4692 rb_hash_aset(lazy_use_super_method, sym(
"uniq"), sym(
"_enumerable_uniq"));
4693 rb_hash_aset(lazy_use_super_method, sym(
"with_index"), sym(
"_enumerable_with_index"));
4695 rb_vm_register_global_object(lazy_use_super_method);
4715 rb_define_method(rb_cGenerator,
"initialize_copy", generator_init_copy, 1);
4736 rb_define_method(rb_cEnumChain,
"initialize_copy", enum_chain_init_copy, 1);
4750 rb_define_method(rb_cEnumProduct,
"initialize", enum_product_initialize, -1);
4751 rb_define_method(rb_cEnumProduct,
"initialize_copy", enum_product_init_copy, 1);
4786Init_Enumerator(
void)
4798 sym_each =
ID2SYM(id_each);
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
void rb_include_module(VALUE klass, VALUE module)
Includes a module to a class.
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
void rb_need_block(void)
Declares that the current method needs a block.
void rb_undef_method(VALUE klass, const char *name)
Defines an undef of a method.
int rb_scan_args_kw(int kw_flag, int argc, const VALUE *argv, const char *fmt,...)
Identical to rb_scan_args(), except it also accepts kw_splat.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Retrieves argument from argc and argv to given VALUE references according to the format string.
int rb_keyword_given_p(void)
Determines if the current method is given a keyword argument.
int rb_block_given_p(void)
Determines if the current method is given a block.
int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
Keyword argument deconstructor.
#define T_COMPLEX
Old name of RUBY_T_COMPLEX.
#define RB_INTEGER_TYPE_P
Old name of rb_integer_type_p.
#define rb_str_buf_cat2
Old name of rb_usascii_str_new_cstr.
#define OBJ_INIT_COPY(obj, orig)
Old name of RB_OBJ_INIT_COPY.
#define RFLOAT_VALUE
Old name of rb_float_value.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define T_FLOAT
Old name of RUBY_T_FLOAT.
#define ID2SYM
Old name of RB_ID2SYM.
#define UNREACHABLE_RETURN
Old name of RBIMPL_UNREACHABLE_RETURN.
#define CLASS_OF
Old name of rb_class_of.
#define rb_ary_new4
Old name of rb_ary_new_from_values.
#define FIXABLE
Old name of RB_FIXABLE.
#define rb_exc_new2
Old name of rb_exc_new_cstr.
#define LONG2FIX
Old name of RB_INT2FIX.
#define T_RATIONAL
Old name of RUBY_T_RATIONAL.
#define T_HASH
Old name of RUBY_T_HASH.
#define NUM2DBL
Old name of rb_num2dbl.
#define rb_ary_new3
Old name of rb_ary_new_from_args.
#define LONG2NUM
Old name of RB_LONG2NUM.
#define Qtrue
Old name of RUBY_Qtrue.
#define ST2FIX
Old name of RB_ST2FIX.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define FIX2LONG
Old name of RB_FIX2LONG.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define NIL_P
Old name of RB_NIL_P.
#define ALLOCV_N
Old name of RB_ALLOCV_N.
#define POSFIXABLE
Old name of RB_POSFIXABLE.
#define T_SYMBOL
Old name of RUBY_T_SYMBOL.
#define DBL2NUM
Old name of rb_float_new.
#define NUM2LONG
Old name of RB_NUM2LONG.
#define FIXNUM_P
Old name of RB_FIXNUM_P.
#define rb_ary_new2
Old name of rb_ary_new_capa.
#define ALLOCV_END
Old name of RB_ALLOCV_END.
#define SYMBOL_P
Old name of RB_SYMBOL_P.
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_iter_break(void)
Breaks from a block.
VALUE rb_eRangeError
RangeError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eRuntimeError
RuntimeError exception.
VALUE rb_eStopIteration
StopIteration exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
VALUE rb_exc_new_str(VALUE etype, VALUE str)
Identical to rb_exc_new_cstr(), except it takes a Ruby's string instead of C's.
VALUE rb_eIndexError
IndexError exception.
VALUE rb_mKernel
Kernel module.
VALUE rb_cObject
Object class.
VALUE rb_mEnumerable
Enumerable module.
VALUE rb_cEnumerator
Enumerator class.
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_cNumeric
Numeric class.
VALUE rb_obj_class(VALUE obj)
Queries the class of an object.
VALUE rb_obj_dup(VALUE obj)
Duplicates the given object.
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
VALUE rb_cRange
Range class.
VALUE rb_equal(VALUE lhs, VALUE rhs)
This function is an optimised version of calling #==.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass)
Queries if the given object is an instance (of possibly descendants) of the given class.
VALUE rb_obj_freeze(VALUE obj)
Same as RB_OBJ_FREEZE(), but returns the given object.
VALUE rb_to_int(VALUE val)
Identical to rb_check_to_int(), except it raises in case of conversion mismatch.
#define RB_OBJ_WRITE(old, slot, young)
Declaration of a "back" pointer.
VALUE rb_funcall(VALUE recv, ID mid, int n,...)
Calls a method.
VALUE rb_funcallv(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcall(), except it takes the method arguments as a C array.
VALUE rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE procval)
Identical to rb_funcallv_public(), except you can pass a block.
VALUE rb_call_super(int argc, const VALUE *argv)
This resembles ruby's super.
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Identical to rb_ary_new_from_args(), except how objects are passed.
VALUE rb_ary_dup(VALUE ary)
Duplicates an array.
VALUE rb_ary_cat(VALUE ary, const VALUE *train, long len)
Destructively appends multiple elements at the end of the array.
VALUE rb_check_array_type(VALUE obj)
Try converting an object to its array representation using its to_ary method, if any.
VALUE rb_ary_new(void)
Allocates a new, empty array.
VALUE rb_ary_new_capa(long capa)
Identical to rb_ary_new(), except it additionally specifies how many rooms of objects it should alloc...
VALUE rb_ary_resize(VALUE ary, long len)
Expands or shrinks the passed array to the passed length.
VALUE rb_ary_hidden_new(long capa)
Allocates a hidden (no class) empty array.
VALUE rb_ary_push(VALUE ary, VALUE elem)
Special case of rb_ary_cat() that it adds only one element.
VALUE rb_ary_freeze(VALUE obj)
Freeze an array, preventing further modifications.
VALUE rb_ary_entry(VALUE ary, long off)
Queries an element of an array.
void rb_ary_store(VALUE ary, long key, VALUE val)
Destructively stores the passed value to the passed array's passed index.
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
This roughly resembles return enum_for(__callee__) unless block_given?.
VALUE rb_enumerator_size_func(VALUE recv, VALUE argv, VALUE eobj)
This is the type of functions that rb_enumeratorize_with_size() expects.
static int rb_check_arity(int argc, int min, int max)
Ensures that the passed integer is in the passed range.
void rb_provide(const char *feature)
Declares that the given feature is already provided by someone else.
VALUE rb_num_coerce_cmp(VALUE lhs, VALUE rhs, ID op)
Identical to rb_num_coerce_bin(), except for return values.
VALUE rb_obj_method(VALUE recv, VALUE mid)
Creates a method object.
VALUE rb_block_proc(void)
Constructs a Proc object from implicitly passed components.
VALUE rb_proc_call_with_block(VALUE recv, int argc, const VALUE *argv, VALUE proc)
Identical to rb_proc_call(), except you can additionally pass another proc object,...
VALUE rb_proc_call_kw(VALUE recv, VALUE args, int kw_splat)
Identical to rb_proc_call(), except you can specify how to handle the last element of the given array...
VALUE rb_obj_is_proc(VALUE recv)
Queries if the given object is a proc.
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
Deconstructs a range into its components.
VALUE rb_set_new(void)
Creates a new, empty set object.
#define rb_hash_uint(h, i)
Just another name of st_hash_uint.
#define rb_hash_end(h)
Just another name of st_hash_end.
VALUE rb_str_append(VALUE dst, VALUE src)
Identical to rb_str_buf_append(), except it converts the right hand side before concatenating.
VALUE rb_str_dup(VALUE str)
Duplicates a string.
VALUE rb_str_buf_append(VALUE dst, VALUE src)
Identical to rb_str_cat_cstr(), except it takes Ruby's string instead of C's.
void rb_str_set_len(VALUE str, long len)
Overwrites the length of the string.
st_index_t rb_hash_start(st_index_t i)
Starts a series of hashing.
VALUE rb_exec_recursive(VALUE(*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h)
"Recursion" API entry point.
VALUE rb_ivar_set(VALUE obj, ID name, VALUE val)
Identical to rb_iv_set(), except it accepts the name as an ID instead of a C string.
VALUE rb_ivar_get(VALUE obj, ID name)
Identical to rb_iv_get(), except it accepts the name as an ID instead of a C string.
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
int rb_respond_to(VALUE obj, ID mid)
Queries if the object responds to the method.
void rb_undef_alloc_func(VALUE klass)
Deletes the allocator function of a class.
VALUE rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv)
Identical to rb_funcallv(), except it returns RUBY_Qundef instead of raising rb_eNoMethodError.
VALUE rb_check_funcall_kw(VALUE recv, ID mid, int argc, const VALUE *argv, int kw_splat)
Identical to rb_check_funcall(), except you can specify how to handle the last element of the given a...
void rb_define_alloc_func(VALUE klass, rb_alloc_func_t func)
Sets the allocator function of a class.
static ID rb_intern_const(const char *str)
This is a "tiny optimisation" over rb_intern().
VALUE rb_sym2str(VALUE symbol)
Obtain a frozen string representation of a symbol (not including the leading colon).
VALUE rb_to_symbol(VALUE name)
Identical to rb_intern_str(), except it generates a dynamic symbol if necessary.
ID rb_to_id(VALUE str)
Identical to rb_intern_str(), except it tries to convert the parameter object to an instance of rb_cS...
int len
Length of the buffer.
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Shim for block function parameters.
VALUE rb_yield_values(int n,...)
Identical to rb_yield(), except it takes variadic number of parameters and pass them to the block.
VALUE rb_yield_values2(int n, const VALUE *argv)
Identical to rb_yield_values(), except it takes the parameters as a C array instead of variadic argum...
VALUE rb_yield(VALUE val)
Yields the block.
VALUE rb_yield_values_kw(int n, const VALUE *argv, int kw_splat)
Identical to rb_yield_values2(), except you can specify how to handle the last element of the given a...
VALUE rb_block_call_func(RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg))
This is the type of a function that the interpreter expect for C-backended blocks.
VALUE rb_block_call_kw(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t proc, VALUE data2, int kw_splat)
Identical to rb_funcallv_kw(), except it additionally passes a function as a block.
#define rb_long2int
Just another name of rb_long2int_inline.
#define MEMCPY(p1, p2, type, n)
Handy macro to call memcpy.
#define RB_GC_GUARD(v)
Prevents premature destruction of local objects.
VALUE rb_block_call(VALUE q, ID w, int e, const VALUE *r, type *t, VALUE y)
Call a method with a block.
VALUE rb_proc_new(type *q, VALUE w)
Creates a rb_cProc instance.
VALUE rb_fiber_new(type *q, VALUE w)
Creates a rb_cFiber instance.
void rb_hash_foreach(VALUE q, int_type *w, VALUE e)
Iteration over the given hash.
VALUE rb_rescue2(type *q, VALUE w, type *e, VALUE r,...)
An equivalent of rescue clause.
#define RARRAY_LEN
Just another name of rb_array_len.
static int RARRAY_LENINT(VALUE ary)
Identical to rb_array_len(), except it differs for the return type.
#define RARRAY_AREF(a, i)
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
#define RHASH_EMPTY_P(h)
Checks if the hash is empty.
#define RUBY_TYPED_DEFAULT_FREE
This is a value you can set to rb_data_type_struct::dfree.
#define TypedData_Get_Struct(obj, type, data_type, sval)
Obtains a C struct from inside of a wrapper Ruby object.
#define TypedData_Make_Struct(klass, type, data_type, sval)
Identical to TypedData_Wrap_Struct, except it allocates a new data region internally instead of takin...
#define InitVM(ext)
This macro is for internal use.
#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS
Treat a final argument as keywords if it is a hash, and not as keywords otherwise.
#define RB_PASS_CALLED_KEYWORDS
Pass keywords if current method is called with keywords, useful for argument delegation.
#define RB_NO_KEYWORDS
Do not pass keywords.
#define RTEST
This is an old name of RB_TEST.
#define _(args)
This was a transition path from K&R to ANSI.
Decomposed Enumerator::ArithmeicSequence.
int exclude_end
Whether the endpoint is open or closed.
VALUE end
"Right" or "highest" endpoint of the sequence.
VALUE step
Step between a sequence.
VALUE begin
"Left" or "lowest" endpoint of the sequence.
This is the struct that holds necessary info for a struct.
VALUE flags
Type-specific behavioural characteristics.
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.
static bool RB_FLOAT_TYPE_P(VALUE obj)
Queries if the object is an instance of rb_cFloat.
static void Check_Type(VALUE v, enum ruby_value_type t)
Identical to RB_TYPE_P(), except it raises exceptions on predication failure.
static bool RB_TYPE_P(VALUE obj, enum ruby_value_type t)
Queries if the given object is of given type.