Ruby 在保持inspect输出的同时覆盖到_s
当我使用puts时,我重写了to_方法以获得漂亮的输出,但同时我似乎失去了检查对象的能力。是否有方法在覆盖到_s时获得inspect的正常输出Ruby 在保持inspect输出的同时覆盖到_s,ruby,oop,overriding,Ruby,Oop,Overriding,当我使用puts时,我重写了to_方法以获得漂亮的输出,但同时我似乎失去了检查对象的能力。是否有方法在覆盖到_s时获得inspect的正常输出 class Person attr_accessor :first, :last, :birthdate def initialize(first=nil, last=nil, birthdate=nil) @first, @last, @birthdate = first, last, birthdate end def age
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>
班级人员
属性访问器:第一个、最后一个、出生日期
def初始化(第一次=零,最后一次=零,出生日期=零)
@first,@last,@birthdate=first,last,birthdate
结束
定义年龄
如果生日
时间,现在,生日
其他的
0
结束
结束
def至美国
“{@first}{@last}({age})”
结束
结束
我=人。新(“彼得”,“玛丽”,1962年)
彼得·玛丽(50岁)
p me.inspect>>“彼得·玛丽(50)”
#需要#
我认为默认情况下,inspect使用to_s方法
但是,您也可以覆盖inspect,包括在覆盖之前将旧的to_s方法别名到它。Ruby文档,默认情况下inspect
使用to_s
作为其输出
如果不需要对象的地址,可以提供自己的inspect,以实现几乎相同的行为:
class Person
def inspect
vars = self.instance_variables.
map{|v| "#{v}=#{instance_variable_get(v).inspect}"}.join(", ")
"<#{self.class}: #{vars}>"
end
end
然后在irb或您的脚本中:
require 'awesome_print'
ap Person.new("John")
还有一个内置的pp
库,具有类似的用途。但它仍然不能免疫(至少在Ruby 1.9.2-p290中)重写到
pp
的一个快速示例:
require 'pp'
pp Person.new("John")
这里是Aleksander的解,第一个p应该给_s覆盖,但是没有,你必须明确地调用第二个p中的_s,以得到我想要的结果。我也不确定这个检查是否会给出与原来的检查相同的结果,因为它包含更复杂的对象,我会在家里尝试。还有更好的吗? 我知道非常棒的打印宝石,但是对于像这样的基本东西,你不需要包括宝石
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>"
班级人员
def初始化(第一次=零,最后一次=零,出生日期=零)
@first,@last,@birthdate=first,last,birthdate
结束
#to_s的新实现
def至美国
“{@first}{@last}”
结束
def检查
vars=self.instance\u变量。
map{v}“{v}={instance_variable_get(v.inspect}”}.join(,”)
""
结束
结束
我=新的人(“约翰”)
p我-->
给我一封信-->“约翰”
请检查-->“”
编辑:我刚刚尝试了awesome_print,我很高兴,担心我必须使用IRB来利用它,但事实并非如此,我在我的编辑器中运行我的脚本
require 'awesome_print'
ap me -->
#<Person:0x027efe20
@birthdate = nil,
@first = "John",
@last = nil
>
要求“绝妙打印”
ap我-->
#
按照Aleksander的建议,使用pretty_print进行编辑,不会干扰覆盖到的
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>
require'PP'
班主任
def初始化(第一次=零,最后一次=零,出生日期=零)
@first,@last,@birthdate=first,last,birthdate
结束
#to_s的新实现
def至美国
“{@first}{@last}”
结束
结束
我=新的人(“约翰”)
pp我-->
警告我。漂亮的检查-->
佩里,这里是我试图让alias或alias_方法工作的众多组合之一,如果你认为这是可行的,你能提交一个工作片段吗
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>"
班级人员
属性访问器:第一个、最后一个、出生日期
def初始化(第一次=零,最后一次=零,出生日期=零)
@first,@last,@birthdate=first,last,birthdate
结束
别名old_to_s to_s
def检查
老外
结束
def至美国
“{@first}{@last}”
结束
结束
我=新的人(“彼得”)
p我-->#
请检查-->“#”
此错误报告讨论了相同的问题:但是我没有看到票证上的任何进展。因此,这是一个错误,我没有意识到..,感谢您提供的链接。您希望使用alias_方法(查找它)来“保存一份”旧to_方法,然后覆盖inspect方法来简单地调用旧to_方法。您也可以只使用alias_方法在覆盖到_s之前将旧的to_s别名为“inspect”——如果可行,这是最简单的方法。Perry不可行,尝试了alias和alias_方法的所有组合,你要么得到两个的美化输出,要么得到bothI的非美化输出。bothI建议的基本上与另一个回答者给出的内容相同,只是有一些小的变化。我认为您可能做得不太对--也许您应该发布您试用过的代码。这不起作用。默认的#to_s不包括实例变量。谢谢,但是。。。p(或puts)不会给出不变的相同结果,并且您的代码会给出以下结果,因此to#s Pretifier不再有效“你能详细说明一下吗?”我不知道预期的行为与提供的代码的行为相比是什么。只需使用更复杂的对象进行尝试,p对象会提供对象以外的其他输出。检查,无论如何,您的代码不起作用,您尝试过吗?它给出了对象表示,而不是修饰和对象表示感谢,这是朝着正确方向迈出的一步,但不是完全正确的。我把结果放在一个答案中,我可以给出布局。如果有循环引用,则失败,例如:丈夫=人。新;妻子=人。新的;丈夫、配偶=妻子;妻子.配偶=丈夫re:awesome\u print
还有pp
(pretty\u print)库,它与Ruby捆绑在一起,具有类似的用途。但是pp
是基于检查的,所以将更改为
会破坏pp
的结果。这不会发生在awesome\u print
上,这就是我推荐使用它的原因。试用过的pp和pretty\u inspect,它们不会与重写的to\s相互恐惧,它在内核中,很好,但您必须需要它,编辑答案以备将来参考,并将您的响应标记为答案,谢谢你的帮助-我尝试了你提供的例子,得到了不同的结果。你使用哪个Ruby版本?另外:你需要'PP'还是'PP'?ruby-v给出了ruby 1.9.3p0(2011-10-30)[i386-mingw32],需要'PP'给出了与需要'PP'相同的结果,会有区别吗?也许是操作系统,我用的是Windows7
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>"