static VALUE
method_inspect(VALUE method)
{
struct METHOD *data;
VALUE str;
const char *s;
const char *sharp = "#";
VALUE mklass;
VALUE defined_class;
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
str = rb_str_buf_new2("#<");
s = rb_obj_classname(method);
rb_str_buf_cat2(str, s);
rb_str_buf_cat2(str, ": ");
mklass = data->klass;
if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
defined_class = data->me->def->body.alias.original_me->owner;
}
else {
defined_class = method_entry_defined_class(data->me);
}
if (RB_TYPE_P(defined_class, T_ICLASS)) {
defined_class = RBASIC_CLASS(defined_class);
}
if (FL_TEST(mklass, FL_SINGLETON)) {
VALUE v = rb_ivar_get(mklass, attached);
if (data->recv == Qundef) {
rb_str_buf_append(str, rb_inspect(mklass));
}
else if (data->recv == v) {
rb_str_buf_append(str, rb_inspect(v));
sharp = ".";
}
else {
rb_str_buf_append(str, rb_inspect(data->recv));
rb_str_buf_cat2(str, "(");
rb_str_buf_append(str, rb_inspect(v));
rb_str_buf_cat2(str, ")");
sharp = ".";
}
}
else {
rb_str_buf_append(str, rb_class_name(mklass));
if (defined_class != mklass) {
rb_str_buf_cat2(str, "(");
rb_str_buf_append(str, rb_class_name(defined_class));
rb_str_buf_cat2(str, ")");
}
}
rb_str_buf_cat2(str, sharp);
rb_str_append(str, rb_id2str(data->me->called_id));
if (data->me->called_id != data->me->def->original_id) {
rb_str_catf(str, "(%"PRIsVALUE")",
rb_id2str(data->me->def->original_id));
}
if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
rb_str_buf_cat2(str, " (not-implemented)");
}
rb_str_buf_cat2(str, ">");
return str;
}