VALUE rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj) { VALUE recur, ary, klass; st_table *list; if (argc == 0) { recur = Qtrue; } else { rb_scan_args(argc, argv, "01", &recur); } klass = CLASS_OF(obj); list = st_init_numtable(); if (klass && FL_TEST(klass, FL_SINGLETON)) { st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list); klass = RCLASS_SUPER(klass); } if (RTEST(recur)) { while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) { st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list); klass = RCLASS_SUPER(klass); } } ary = rb_ary_new(); st_foreach(list, ins_methods_i, ary); st_free_table(list); return ary; }
VALUE rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj) { VALUE recur, ary, klass, origin; st_table *list, *mtbl; if (argc == 0) { recur = Qtrue; } else { rb_scan_args(argc, argv, "01", &recur); } klass = CLASS_OF(obj); origin = RCLASS_ORIGIN(klass); list = st_init_numtable(); if (klass && FL_TEST(klass, FL_SINGLETON)) { if ((mtbl = RCLASS_M_TBL(origin)) != 0) st_foreach(mtbl, method_entry_i, (st_data_t)list); klass = RCLASS_SUPER(klass); } if (RTEST(recur)) { while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) { if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) st_foreach(mtbl, method_entry_i, (st_data_t)list); klass = RCLASS_SUPER(klass); } } ary = rb_ary_new(); st_foreach(list, ins_methods_i, ary); st_free_table(list); return ary; }
void rb_undef(VALUE klass, ID id) { VALUE origin; NODE *body; if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) { rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'", rb_id2name(id)); } rb_frozen_class_p(klass); if (id == object_id || id == __send__ || id == idInitialize) { rb_warn("undefining `%s' may cause serious problem", rb_id2name(id)); } body = search_method(klass, id, &origin); if (!body || !body->nd_body) { const char *s0 = " class"; VALUE c = klass; if (FL_TEST(c, FL_SINGLETON)) { VALUE obj = rb_iv_get(klass, "__attached__"); switch (TYPE(obj)) { case T_MODULE: case T_CLASS: c = obj; s0 = ""; } } else if (TYPE(c) == T_MODULE) { s0 = " module"; } rb_name_error(id, "undefined method `%s' for%s `%s'", rb_id2name(id), s0, rb_class2name(c)); } rb_add_method(klass, id, 0, NOEX_PUBLIC); if (FL_TEST(klass, FL_SINGLETON)) { rb_funcall(rb_iv_get(klass, "__attached__"), singleton_undefined, 1, ID2SYM(id)); } else { rb_funcall(klass, undefined, 1, ID2SYM(id)); } }
static VALUE singleton_class_clone_int(VALUE obj, VALUE nklass) { VALUE klass = RBASIC(obj)->klass; if (!FL_TEST(klass, FL_SINGLETON)) return klass; else { /* copy singleton(unnamed) class */ NEWOBJ(clone, struct RClass); OBJSETUP(clone, 0, RBASIC(klass)->flags); if (BUILTIN_TYPE(obj) == T_CLASS) { RBASIC(clone)->klass = (VALUE)clone; } else { RBASIC(clone)->klass = rb_singleton_class_clone(klass); } clone->super = RCLASS(klass)->super; clone->iv_tbl = 0; clone->m_tbl = 0; if (RCLASS(klass)->iv_tbl) { clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl); } clone->m_tbl = st_init_numtable(); st_foreach(RCLASS(klass)->m_tbl, (int (*)(...))clone_method, NIL_P(nklass) ? (VALUE)clone : nklass); rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); FL_SET(clone, FL_SINGLETON); return (VALUE)clone; } }
static int total_i(void *vstart, void *vend, size_t stride, void *ptr) { VALUE v; struct total_data *data = (struct total_data *)ptr; for (v = (VALUE)vstart; v != (VALUE)vend; v += stride) { if (RBASIC(v)->flags) { switch (BUILTIN_TYPE(v)) { case T_NONE: case T_ICLASS: case T_NODE: case T_ZOMBIE: continue; case T_CLASS: if (FL_TEST(v, FL_SINGLETON)) continue; default: if (data->klass == 0 || rb_obj_is_kind_of(v, data->klass)) { data->total += memsize_of(v); } } } } return 0; }
static VALUE superclass_name(VALUE module) { if(TYPE(module) == T_MODULE) { return Qnil; } else { VALUE super = RCLASS_SUPER(module); while(TYPE(super) == T_ICLASS) { super = RCLASS_SUPER(super); } if(!super) { return Qnil; } if(FL_TEST(super, FL_SINGLETON)) { VALUE v = rb_iv_get(super, "__attached__"); VALUE name = rb_mod_name(v); rb_str_cat2(name, "::<Singleton>"); return name; } else { return rb_mod_name(super); } } }
static void call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klass) { const char *srcfile = rb_sourcefile(); VALUE eventname = rb_str_new2(get_event_name(event)); VALUE filename = srcfile ? rb_str_new2(srcfile) : Qnil; VALUE argv[6]; int line = rb_sourceline(); rb_thread_t *th = GET_THREAD(); if (!klass) { rb_thread_method_id_and_class(th, &id, &klass); } if (klass) { if (RB_TYPE_P(klass, T_ICLASS)) { klass = RBASIC(klass)->klass; } else if (FL_TEST(klass, FL_SINGLETON)) { klass = rb_iv_get(klass, "__attached__"); } } argv[0] = eventname; argv[1] = filename; argv[2] = INT2FIX(line); argv[3] = id ? ID2SYM(id) : Qnil; argv[4] = (self && srcfile) ? rb_binding_new() : Qnil; argv[5] = klass ? klass : Qnil; rb_proc_call_with_block(proc, 6, argv, Qnil); }
/* :nodoc: */ VALUE rb_mod_init_copy(VALUE clone, VALUE orig) { rb_obj_init_copy(clone, orig); if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { RBASIC(clone)->klass = rb_singleton_class_clone(orig); } RCLASS_SUPER(clone) = RCLASS_SUPER(orig); if (RCLASS_IV_TBL(orig)) { ID id; RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig)); CONST_ID(id, "__classpath__"); st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0); CONST_ID(id, "__classid__"); st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0); } if (RCLASS_M_TBL(orig)) { struct clone_method_data data; data.tbl = RCLASS_M_TBL(clone) = st_init_numtable(); data.klass = clone; st_foreach(RCLASS_M_TBL(orig), clone_method, (st_data_t)&data); } return clone; }
void rb_gc_copy_finalizer(VALUE dest, VALUE obj) { VALUE table; if (__os_finalizers == NULL) return; if (NATIVE(obj)) { if (!rb_objc_flag_check((void *)obj, FL_FINALIZE)) return; } else { if (!FL_TEST(obj, FL_FINALIZE)) return; } table = (VALUE)CFDictionaryGetValue((CFDictionaryRef)__os_finalizers, (const void *)obj); if (table == 0) { CFDictionaryRemoveValue(__os_finalizers, (const void *)dest); } else { CFDictionarySetValue(__os_finalizers, (const void *)dest, (const void *)table); } }
static VALUE klass_name(VALUE klass) { VALUE result = Qnil; if (klass == 0 || klass == Qnil) { result = rb_str_new2("Global"); } else if (BUILTIN_TYPE(klass) == T_MODULE) { result = rb_inspect(klass); } else if (BUILTIN_TYPE(klass) == T_CLASS && FL_TEST(klass, FL_SINGLETON)) { result = figure_singleton_name(klass); } else if (BUILTIN_TYPE(klass) == T_CLASS) { result = rb_inspect(klass); } else { /* Should never happen. */ result = rb_str_new2("Unknown"); } return result; }
VALUE rb_singleton_class(VALUE obj) { VALUE klass; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } DEFER_INTS; if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); ALLOW_INTS; return klass; }
VALUE rb_singleton_class_clone(VALUE obj) { VALUE klass = RBASIC(obj)->klass; if (!FL_TEST(klass, FL_SINGLETON)) return klass; else { struct clone_method_data data; /* copy singleton(unnamed) class */ VALUE clone = class_alloc(RBASIC(klass)->flags, 0); if (BUILTIN_TYPE(obj) == T_CLASS) { RBASIC(clone)->klass = (VALUE)clone; } else { RBASIC(clone)->klass = rb_singleton_class_clone(klass); } RCLASS_SUPER(clone) = RCLASS_SUPER(klass); if (RCLASS_IV_TBL(klass)) { RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass)); } RCLASS_M_TBL(clone) = st_init_numtable(); data.tbl = RCLASS_M_TBL(clone); data.klass = (VALUE)clone; st_foreach(RCLASS_M_TBL(klass), clone_method, (st_data_t)&data); rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); FL_SET(clone, FL_SINGLETON); return (VALUE)clone; } }
static VALUE class_instance_method_list(int argc, VALUE *argv, VALUE mod, int obj, int (*func) (st_data_t, st_data_t, st_data_t)) { VALUE ary; int recur, prepended = 0; st_table *list; if (argc == 0) { recur = TRUE; } else { VALUE r; rb_scan_args(argc, argv, "01", &r); recur = RTEST(r); } if (!recur && RCLASS_ORIGIN(mod) != mod) { mod = RCLASS_ORIGIN(mod); prepended = 1; } list = st_init_numtable(); for (; mod; mod = RCLASS_SUPER(mod)) { if (RCLASS_M_TBL(mod)) st_foreach(RCLASS_M_TBL(mod), method_entry_i, (st_data_t)list); if (BUILTIN_TYPE(mod) == T_ICLASS && !prepended) continue; if (obj && FL_TEST(mod, FL_SINGLETON)) continue; if (!recur) break; } ary = rb_ary_new(); st_foreach(list, func, ary); st_free_table(list); return ary; }
/*! * Creates a meta^(n+1)-class for a meta^(n)-class. * \param metaclass a class of a class * \return the created meta^(n+1)-class. * \pre \a metaclass is a metaclass * \post the class of \a metaclass is the returned class. */ static VALUE make_metametaclass(VALUE metaclass) { VALUE metametaclass, super_of_metaclass; if (RBASIC(metaclass)->klass == metaclass) { /* for meta^(n)-class of Class */ metametaclass = rb_class_boot(Qnil); RBASIC(metametaclass)->klass = metametaclass; } else { metametaclass = rb_class_boot(Qnil); RBASIC(metametaclass)->klass = (RBASIC(RBASIC(metaclass)->klass)->klass == RBASIC(metaclass)->klass) ? make_metametaclass(RBASIC(metaclass)->klass) : RBASIC(RBASIC(metaclass)->klass)->klass; } FL_SET(metametaclass, FL_SINGLETON); rb_singleton_class_attached(metametaclass, metaclass); RBASIC(metaclass)->klass = metametaclass; super_of_metaclass = RCLASS_SUPER(metaclass); while (FL_TEST(super_of_metaclass, T_ICLASS)) { super_of_metaclass = RCLASS_SUPER(super_of_metaclass); } RCLASS_SUPER(metametaclass) = rb_iv_get(RBASIC(super_of_metaclass)->klass, "__attached__") == super_of_metaclass ? RBASIC(super_of_metaclass)->klass : make_metametaclass(super_of_metaclass); OBJ_INFECT(metametaclass, RCLASS_SUPER(metametaclass)); return metametaclass; }
static VALUE class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, long, VALUE)) { VALUE ary; int recur; st_table *list; if (argc == 0) { recur = TRUE; } else { VALUE r; rb_scan_args(argc, argv, "01", &r); recur = RTEST(r); } list = st_init_numtable(); for (; mod; mod = RCLASS_SUPER(mod)) { st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list); if (BUILTIN_TYPE(mod) == T_ICLASS) continue; if (FL_TEST(mod, FL_SINGLETON)) continue; if (!recur) break; } ary = rb_ary_new(); st_foreach(list, func, ary); st_free_table(list); return ary; }
static int include_modules_at(const VALUE klass, VALUE c, VALUE module) { VALUE p, iclass; int method_changed = 0, constant_changed = 0; const st_table *const klass_m_tbl = RCLASS_M_TBL(RCLASS_ORIGIN(klass)); while (module) { int superclass_seen = FALSE; if (RCLASS_ORIGIN(module) != module) goto skip; if (klass_m_tbl && klass_m_tbl == RCLASS_M_TBL(module)) return -1; /* ignore if the module included already in superclasses */ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) { switch (BUILTIN_TYPE(p)) { case T_ICLASS: if (RCLASS_M_TBL_WRAPPER(p) == RCLASS_M_TBL_WRAPPER(module)) { if (!superclass_seen) { c = p; /* move insertion point */ } goto skip; } break; case T_CLASS: superclass_seen = TRUE; break; } } iclass = rb_include_class_new(module, RCLASS_SUPER(c)); c = RCLASS_SET_SUPER(c, iclass); if (BUILTIN_TYPE(module) == T_ICLASS) { rb_module_add_to_subclasses_list(RBASIC(module)->klass, iclass); } else { rb_module_add_to_subclasses_list(module, iclass); } if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) { VALUE refined_class = rb_refinement_module_get_refined_class(klass); st_foreach(RMODULE_M_TBL(module), add_refined_method_entry_i, (st_data_t) refined_class); FL_SET(c, RMODULE_INCLUDED_INTO_REFINEMENT); } if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries) method_changed = 1; if (RMODULE_CONST_TBL(module) && RMODULE_CONST_TBL(module)->num_entries) constant_changed = 1; skip: module = RCLASS_SUPER(module); } if (method_changed) rb_clear_method_cache_by_class(klass); if (constant_changed) rb_clear_constant_cache(); return method_changed; }
void rb_alias(VALUE klass, ID name, ID def) { NODE *orig_fbody, *node, *method; VALUE singleton = 0; st_data_t data; rb_frozen_class_p(klass); if (klass == rb_cObject) { rb_secure(4); } orig_fbody = search_method(klass, def, 0); if (!orig_fbody || !orig_fbody->nd_body) { if (TYPE(klass) == T_MODULE) { orig_fbody = search_method(rb_cObject, def, 0); } } if (!orig_fbody || !orig_fbody->nd_body) { rb_print_undef(klass, def, 0); } if (FL_TEST(klass, FL_SINGLETON)) { singleton = rb_iv_get(klass, "__attached__"); } orig_fbody->nd_cnt++; if (st_lookup(RCLASS_M_TBL(klass), name, &data)) { node = (NODE *)data; if (node) { if (RTEST(ruby_verbose) && node->nd_cnt == 0 && node->nd_body) { rb_warning("discarding old %s", rb_id2name(name)); } if (nd_type(node->nd_body->nd_body) == NODE_CFUNC) { rb_vm_check_redefinition_opt_method(node); } } } st_insert(RCLASS_M_TBL(klass), name, (st_data_t) NEW_FBODY( method = NEW_METHOD(orig_fbody->nd_body->nd_body, orig_fbody->nd_body->nd_clss, NOEX_WITH_SAFE(orig_fbody->nd_body->nd_noex)), def)); method->nd_file = (void *)def; rb_clear_cache_by_id(name); if (!ruby_running) return; if (singleton) { rb_funcall(singleton, singleton_added, 1, ID2SYM(name)); } else { rb_funcall(klass, added, 1, ID2SYM(name)); } }
VALUE Looksee_singleton_instance(VALUE self, VALUE klass) { if (!SPECIAL_CONST_P(klass) && BUILTIN_TYPE(klass) == T_CLASS && FL_TEST(klass, FL_SINGLETON)) { VALUE object; if (!Looksee_method_table_lookup(RCLASS_IV_TBL(klass), rb_intern("__attached__"), (st_data_t *)&object)) rb_raise(rb_eRuntimeError, "[looksee bug] can't find singleton object"); return object; } else { return Qnil; } }
VALUE Looksee_singleton_instance(VALUE self, VALUE singleton_class) { if (BUILTIN_TYPE(singleton_class) == T_CLASS && FL_TEST(singleton_class, FL_SINGLETON)) { VALUE object; if (!Looksee_method_table_lookup(RCLASS_IV_TBL(singleton_class), rb_intern("__attached__"), (st_data_t *)&object)) rb_raise(rb_eRuntimeError, "[looksee bug] can't find singleton object"); return object; } else { rb_raise(rb_eTypeError, "expected singleton class, got %s", rb_obj_classname(singleton_class)); } }
/*! * Attach a object to a singleton class. * @pre \a klass is the singleton class of \a obj. */ void rb_singleton_class_attached(VALUE klass, VALUE obj) { if (FL_TEST(klass, FL_SINGLETON)) { if (!RCLASS_IV_TBL(klass)) { RCLASS_IV_TBL(klass) = st_init_numtable(); } st_insert(RCLASS_IV_TBL(klass), id_attached, obj); } }
void rb_singleton_class_attached(VALUE klass, VALUE obj) { if (FL_TEST(klass, FL_SINGLETON)) { if (!RCLASS(klass)->iv_tbl) { RCLASS(klass)->iv_tbl = st_init_numtable(); } st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj); } }
VALUE rb_profile_frame_singleton_method_p(VALUE frame) { VALUE klass = rb_iseq_klass(frame2iseq(frame)); if (klass && !NIL_P(klass) && FL_TEST(klass, FL_SINGLETON)) { return Qtrue; } else { return Qfalse; } }
/* :nodoc: */ VALUE rb_class_init_copy(VALUE clone, VALUE orig) { if (RCLASS_SUPER(clone) != 0) { rb_raise(rb_eTypeError, "already initialized class"); } if (FL_TEST(orig, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't copy singleton class"); } return rb_mod_init_copy(clone, orig); }
void rb_singleton_class_attached(VALUE klass, VALUE obj) { if (FL_TEST(klass, FL_SINGLETON)) { ID attached; if (!RCLASS_IV_TBL(klass)) { RCLASS_IV_TBL(klass) = st_init_numtable(); } CONST_ID(attached, "__attached__"); st_insert(RCLASS_IV_TBL(klass), attached, obj); } }
VALUE rb_class_new(VALUE super) { Check_Type(super, T_CLASS); if (super == rb_cClass) { rb_raise(rb_eTypeError, "can't make subclass of Class"); } if (FL_TEST(super, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't make subclass of virtual class"); } return rb_class_boot(super); }
/*! * Returns the singleton class of \a obj, or nil if obj is not a * singleton object. * * \param obj an arbitrary object. * \return the singleton class or nil. */ VALUE rb_singleton_class_get(VALUE obj) { VALUE klass; if (SPECIAL_CONST_P(obj)) { return rb_special_singleton_class(obj); } klass = RBASIC(obj)->klass; if (!FL_TEST(klass, FL_SINGLETON)) return Qnil; if (rb_ivar_get(klass, id_attached) != obj) return Qnil; return klass; }
static void class_init_copy_check(VALUE clone, VALUE orig) { if (orig == rb_cBasicObject) { rb_raise(rb_eTypeError, "can't copy the root class"); } if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) { rb_raise(rb_eTypeError, "already initialized class"); } if (FL_TEST(orig, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't copy singleton class"); } }
static void test_garbage_collect(void) { void* p; p = mini_gc_malloc(100); #if 0 assert(FL_TEST((((Header*)p) - 1), FL_ALLOC)); #endif p = 0; garbage_collect(); }
/* * call-seq: * module.dump(limit) => String * * Dump a module to a string. The module will be dumped along with its * instance methods, class variables, names of included modules, name of * superclass, its entire metaclass, and the name of the class. * * Note that on ruby 1.8 and newer the module is temporarily modified * while dumping in order to allow singleton classes to be dumped. To * prevent access to the modifed module, Thread.critical is temporarily * set, then restored to its original value once dumping is complete. * Note also that because YARV does not support Thread.critical, the * user must synchronize access to the class with a Mutex in order to * prevent accessing the modified class. */ static VALUE module_dump(VALUE self, VALUE limit) { VALUE flags, instance_methods, class_variables; VALUE included_modules, superclass, metaclass, arr, str, class_name; limit = INT2NUM(NUM2INT(limit) - 1); if(rb_safe_level() >= 4) { /* no access to potentially sensitive data from the sandbox */ rb_raise(rb_eSecurityError, "Insecure: can't dump module"); } flags = INT2NUM(RBASIC(self)->flags); instance_methods = instance_method_hash(self); class_variables = class_variable_hash(self); included_modules = included_modules_list(self); superclass = superclass_name(self); arr = rb_ary_new(); if(FL_TEST(self, FL_SINGLETON)) { metaclass = Qnil; class_name = Qnil; } else { metaclass = rb_singleton_class(self); class_name = rb_class_path(self); } rb_ary_push(arr, flags); rb_ary_push(arr, marshal_dump(instance_methods, limit)); rb_ary_push(arr, marshal_dump(class_variables, limit)); rb_ary_push(arr, included_modules); rb_ary_push(arr, superclass); rb_ary_push(arr, marshal_dump(metaclass, limit)); rb_ary_push(arr, class_name); str = marshal_dump(arr, limit); #if RUBY_VERSION_CODE > 180 { VALUE class_restorer = create_class_restorer(self); rb_iv_set(str, "__class_restorer__", class_restorer); set_class_restore_state(self); } #endif return str; }
int rb_obj_respond_to(VALUE obj, ID id, int priv) { VALUE klass = CLASS_OF(obj); if (rb_method_basic_definition_p(klass, idRespond_to)) { return basic_obj_respond_to(obj, id, !priv); } else { int argc = 1; VALUE args[2]; args[0] = ID2SYM(id); args[1] = Qtrue; if (priv) { if (rb_obj_method_arity(obj, idRespond_to) != 1) { argc = 2; } else if (!NIL_P(ruby_verbose)) { VALUE klass = CLASS_OF(obj); VALUE location = rb_mod_method_location(klass, idRespond_to); rb_warn("%"PRIsVALUE"%c""respond_to?(:%"PRIsVALUE") is" " old fashion which takes only one parameter", (FL_TEST(klass, FL_SINGLETON) ? obj : klass), (FL_TEST(klass, FL_SINGLETON) ? '.' : '#'), QUOTE_ID(id)); if (!NIL_P(location)) { VALUE path = RARRAY_AREF(location, 0); VALUE line = RARRAY_AREF(location, 1); if (!NIL_P(path)) { rb_compile_warn(RSTRING_PTR(path), NUM2INT(line), "respond_to? is defined here"); } } } } return RTEST(rb_funcall2(obj, idRespond_to, argc, args)); } }