在保持检查输出的同时覆盖 to_s

pet*_*ter 4 ruby oop overriding

当我使用 puts 时,我覆盖了 to_s 方法以获得漂亮的输出,但同时我似乎失去了检查对象的能力。有没有办法在覆盖 to_s 的同时获得检查的正常输出?

class Person
  attr_accessor :first, :last, :birthdate
  def initialize(first=nil, last=nil, birthdate=nil)
    @first, @last, @birthdate = first, last, birthdate
  end
  def age
    if birthdate
      Time.now.year-birthdate
    else
      0
    end
  end
  def to_s
    "#{@first} #{@last} (#{age})"
  end
end

me = Person.new("Peter", "Marien", 1962)
p me  >>Peter Marien (50)
p me.inspect  >>"Peter Marien (50)"

#Need #<Person:0x1ec2550 @first="Peter", @last="Marien", @birthdate=1962>
Run Code Online (Sandbox Code Playgroud)

Ale*_*ohl 5

Ruby文档中明确指出,在默认情况下inspect使用to_s其输出。

如果您不需要对象的地址,您可以提供自己的检查,以具有几乎相同的行为:

class Person
  def inspect
    vars = self.instance_variables.
      map{|v| "#{v}=#{instance_variable_get(v).inspect}"}.join(", ")
    "<#{self.class}: #{vars}>"
  end
end
Run Code Online (Sandbox Code Playgroud)

但是你也可以安装一个名为 gem 的awesome_print,它会提供非常好的输出。首先在控制台:

$ gem install awesome_print
Run Code Online (Sandbox Code Playgroud)

然后在 irb 或您的脚本中:

require 'awesome_print'
ap Person.new("John")
Run Code Online (Sandbox Code Playgroud)

还有一个内置pp库,具有类似的目的。它仍然不能(至少在 Ruby 1.9.2-p290 中)覆盖to_s.

一个简单的例子pp:

require 'pp'
pp Person.new("John")
Run Code Online (Sandbox Code Playgroud)