我覆盖to_s方法,以便在我使用puts时得到漂亮的输出,但同时我似乎失去了检查对象的能力。有没有办法在覆盖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>
答案 0 :(得分:4)
Ruby文档clearly states,默认情况下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
但你也可以安装一个名为awesome_print
的宝石,它会提供非常好的输出。
首先在控制台中:
$ gem install awesome_print
然后在irb或你的脚本中:
require 'awesome_print'
ap Person.new("John")
还有一个内置的pp
库,其目的相似。仍然不能免于(至少在Ruby 1.9.2-p290中)覆盖to_s
。
pp
的简短示例:
require 'pp'
pp Person.new("John")
答案 1 :(得分:0)
我相信默认情况下使用to_s方法。
但是,您也可以覆盖inspect,包括在覆盖之前将旧的to_s方法别名化。
答案 2 :(得分:0)
这里是Aleksander的解决方案,第一个p应该给出被覆盖的to_s但是没有,你必须像第二个p中那样明确地调用to_s来得到我想要的结果。我也不确定这个检查会给出与原始的更复杂物体相同的结果,我会在家里试试。谁还有更好的射门? 我知道awesome_print宝石,但恕我直言,你不应该包含宝石。
class Person
def initialize(first=nil, last=nil, birthdate=nil)
@first, @last, @birthdate = first, last, birthdate
end
# New implementation of to_s
def to_s
"#{@first} #{@last}"
end
def inspect
vars = self.instance_variables.
map{|v| "#{v}=#{instance_variable_get(v).inspect}"}.join(", ")
"<#{self.class}: #{vars}>"
end
end
me = Person.new("John")
p me #--><Person: @first="John", @last=nil, @birthdate=nil>
p me.to_s #-->"John "
p me.inspect #-->"<Person: @first=\"John\", @last=nil, @birthdate=nil>"
编辑:我刚尝试了awesome_print,我很高兴,我担心我不得不使用IRB来使用它,但事实并非如此,我在编辑器中运行我的脚本
require 'awesome_print'
ap me -->
#<Person:0x027efe20
@birthdate = nil,
@first = "John",
@last = nil
>
按照Aleksander的建议使用pretty_print进行编辑,不会干扰被覆盖的to_s
require 'PP'
class Person
def initialize(first=nil, last=nil, birthdate=nil)
@first, @last, @birthdate = first, last, birthdate
end
# New implementation of to_s
def to_s
"#{@first} #{@last}"
end
end
me = Person.new("John")
pp me #--> <Person: @first="John", @last=nil, @birthdate=nil>
warn me.pretty_inspect #--> <Person: @first="John", @last=nil, @birthdate=nil>
答案 3 :(得分:0)
Perry,这是我试图获得别名或alias_method工作的众多组合之一,如果您认为这样做,可以提交一个工作片段吗?
class Person
attr_accessor :first, :last, :birthdate
def initialize(first=nil, last=nil, birthdate=nil)
@first, @last, @birthdate = first, last, birthdate
end
alias old_to_s to_s
def inspect
old_to_s
end
def to_s
"#{@first} #{@last}"
end
end
me = Person.new("Peter")
p me #-->#<Person:0x1da26b8>
p me.inspect #-->"#<Person:0x1da26b8>"