Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why aren't instance variables listed in inspect for the subclasses of built-in classes?

Why is there a change in behaviour in inspect when I subclass the built in class. But not seen when I am subclassing a custom one.

class MainError
end

class AnotherTestError < StandardError
  def initialize
    @label_test = "hey!"
  end
end

class TestError < MainError
  def initialize
    @label_test = "hey!"
  end
end

a = AnotherTestError.new
puts a.inspect # output: #<AnotherTestError: AnotherTestError>

t = TestError.new
puts t.inspect # output: #<TestError:0x007f99e12409f0 @label_test="hey!">
like image 883
Jikku Jose Avatar asked May 25 '14 14:05

Jikku Jose


1 Answers

Because many (most? all?) built-in classes

  • are written in C, and
  • have #inspect overriden.

For example, Exception (super class of StandardError) defines #inspect as follows:

exc_inspect(VALUE exc)
{
    VALUE str, klass;

    klass = CLASS_OF(exc);
    exc = rb_obj_as_string(exc);
    if (RSTRING_LEN(exc) == 0) {
        return rb_str_dup(rb_class_name(klass));
    }

    str = rb_str_buf_new2("#<");
    klass = rb_class_name(klass);
    rb_str_buf_append(str, klass);
    rb_str_buf_cat(str, ": ", 2);
    rb_str_buf_append(str, exc);
    rb_str_buf_cat(str, ">", 1);

    return str;
}

The interesting part is building the return string.


Object#inspect, on the other hand defines:

static VALUE
rb_obj_inspect(VALUE obj)
{
    if (rb_ivar_count(obj) > 0) {
        VALUE str;
        VALUE c = rb_class_name(CLASS_OF(obj));

        str = rb_sprintf("-<%"PRIsVALUE":%p", c, (void*)obj);
        return rb_exec_recursive(inspect_obj, obj, str);
    }
    else {
        return rb_any_to_s(obj);
    }
}

which recursively includes the instance variables with name and value.

like image 115
DMKE Avatar answered Sep 21 '22 17:09

DMKE