VALUE rb_block_call(VALUE obj, ID mid, int argc, VALUE *argv, VALUE (*bl_proc) (ANYARGS), VALUE data2) { SEL sel = rb_vm_id_to_sel(mid, argc); return rb_objc_block_call(obj, sel, argc, argv, bl_proc, data2); }
static inline VALUE rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, int scope, bool pass_current_block) { SEL sel; if (mid == ID_ALLOCATOR) { sel = selAlloc; } else { sel = rb_vm_id_to_sel(mid, argc); } rb_vm_block_t *block = pass_current_block ? rb_vm_current_block() : NULL; return rb_vm_call2(block, recv, CLASS_OF(recv), sel, argc, argv); }
/* * call-seq: * obj.to_enum(method = :each, *args) * obj.enum_for(method = :each, *args) * * Returns Enumerator.new(self, method, *args). * * e.g.: * * str = "xyz" * * enum = str.enum_for(:each_byte) * a = enum.map {|b| '%02x' % b } #=> ["78", "79", "7a"] * * # protects an array from being modified * a = [1, 2, 3] * some_method(a.to_enum) * */ static VALUE obj_to_enum(VALUE obj, SEL sel, int argc, VALUE *argv) { VALUE meth = sym_each; if (argc > 0) { --argc; meth = *argv++; } ID meth_id = rb_to_id(meth); SEL enum_sel = rb_vm_id_to_sel(meth_id, argc); return rb_enumeratorize(obj, enum_sel, argc, argv); }
static VALUE rb_mod_define_method(VALUE mod, SEL sel, int argc, VALUE *argv) { #if MACRUBY_STATIC not_implemented_in_static(sel); #else ID id; VALUE body; if (argc == 1) { id = rb_to_id(argv[0]); body = rb_block_lambda(); } else if (argc == 2) { id = rb_to_id(argv[0]); body = argv[1]; if (!rb_obj_is_method(body) && !rb_obj_is_proc(body)) { rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Method)", rb_obj_classname(body)); } } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc); } if (rb_obj_is_method(body)) { rb_vm_method_t *data; Data_Get_Struct(body, rb_vm_method_t, data); if (data->node == NULL) { rb_raise(rb_eArgError, "cannot use Method object of pure Objective-C method"); } SEL msel = rb_vm_id_to_sel(id, data->arity); rb_vm_define_method2((Class)mod, msel, data->node, data->node->flags, false); } else { rb_vm_block_t *proc; GetProcPtr(body, proc); rb_vm_define_method3((Class)mod, id, proc); } return body; #endif }
/* * call-seq: * Enumerator.new(obj, method = :each, *args) * Enumerator.new { |y| ... } * * Creates a new Enumerator object, which is to be used as an * Enumerable object iterating in a given way. * * In the first form, a generated Enumerator iterates over the given * object using the given method with the given arguments passed. * Use of this form is discouraged. Use Kernel#enum_for(), alias * to_enum, instead. * * e = Enumerator.new(ObjectSpace, :each_object) * #-> ObjectSpace.enum_for(:each_object) * * e.select { |obj| obj.is_a?(Class) } #=> array of all classes * * In the second form, iteration is defined by the given block, in * which a "yielder" object given as block parameter can be used to * yield a value by calling the +yield+ method, alias +<<+. * * fib = Enumerator.new { |y| * a = b = 1 * loop { * y << a * a, b = b, a + b * } * } * * p fib.take(10) #=> [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] */ static VALUE enumerator_initialize(VALUE obj, SEL sel, int argc, VALUE *argv) { VALUE recv, meth = sym_each; if (argc == 0) { if (!rb_block_given_p()) rb_raise(rb_eArgError, "wrong number of argument (0 for 1+)"); recv = generator_init(generator_allocate(rb_cGenerator, 0), rb_block_proc()); } else { recv = *argv++; if (--argc) { meth = *argv++; --argc; } } ID meth_id = rb_to_id(meth); SEL meth_sel = rb_vm_id_to_sel(meth_id, argc); return enumerator_init(obj, recv, meth_sel, argc, argv); }