【问题标题】:Why aren't instance variables listed in inspect for the subclasses of built-in classes?为什么检查内置类的子类中没有列出实例变量?
【发布时间】:2014-05-25 14:59:04
【问题描述】:

为什么当我对内置类进行子类化时,inspect 的行为会发生变化。但是当我继承一个自定义的子类时没有看到。

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!">

【问题讨论】:

  • 非常好的问题! +1

标签: ruby inheritance subclass


【解决方案1】:

因为许多(大多数?全部?)内置类

  • 用 C 语言编写,并且
  • 已覆盖#inspect

例如,ExceptionStandardError 的超类)定义 #inspect 如下:

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;
}

有趣的部分是构建返回字符串。


Object#inspect,另一方面定义:

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);
    }
}

它递归地包含具有名称和值的实例变量。

【讨论】:

  • 是的..它已被覆盖。
  • 确实,“覆盖”是我缺少的词。谢谢:-)
  • 检查它的定义位置:StandardError.instance_method(:inspect).owner # =&gt; Exception
  • 但我不明白为什么它被覆盖了?
  • 我猜堆栈跟踪是一种以这种形式显示的野兽。此外,如果您需要处理异常(子)类,您的代码已经在 rescue 块中,并且应该正确处理异常(即,将 e.messagee.backtrace 记录到日志文件/ $stderr 而不仅仅是将e.inspect 打印到$stdout)...
猜你喜欢
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多