假设我们有一个相当简单的Java bean:
public class Test {
private String thing;
public void setThing(String thing) {
this.thing = thing;
}
public String getThing() {
return thing;
}
@Override
public String toString() {
return "Test{thing=" + thing + "}>";
}
}
然后我们使用Ruby中的这个bean:
java_import 'Test'
t = Test.new
t.thing = 'blah'
p t
输出结果为:
#<Java::Default::Test:0x5fdba6f9>
但我认为我更喜欢的是
#<Test{thing=blah}>
或者甚至可能只是
Test{thing=blah}
我知道我可以在所有Java类中添加一个名为inspect()
的方法,但似乎每个实现只会调用toString()
,因为{{1}的意图在Java中,通常与Ruby中的toString()
的意图相同(即,仅供开发人员看到的字符串)。
所以我想知道的是,在任何Java对象上调用#inspect
时,有没有一种简单的方法可以告诉JRuby使用toString()
?
答案 0 :(得分:1)
好吧,在任何其他ruby实现中,我们只会修补Object#inspect
方法,但这对Java类来说是不可能的,因为它们的实现是本机的。但是你可以做这样的事情来让你的生活更轻松:
module JavaInspect
alias_method :inspect_without_to_string, :inspect
def inspect_with_string
self.respond_to?(:toString) ? self.toString : self.inspect_without_to_string
end
alias_method :inspect, :inspect_with_string
end
java_import 'Test'
Test.include(JavaInspect)
t = Test.new
t.inspect => "Test{thing=null}>"
t.inspect_without_to_string => "#<Java::Default::Test:0x4efac082>"
您只需将模块包含在所需的类中即可。如果你真的喜欢它,你甚至可以在java_import
周围创建一个包装器。
请注意,我不建议修补猴子Object
,或者为生产代码创建这样的包装器,但是在开发中这可能非常有用,并且在某些情况下经过仔细考虑后可能会甚至可以用于生产。