Reputation: 12680
Say we have a fairly straightforward 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 + "}>";
}
}
And then we use this bean from Ruby:
java_import 'Test'
t = Test.new
t.thing = 'blah'
p t
The output is:
#<Java::Default::Test:0x5fdba6f9>
But I think what I'd prefer is something like
#<Test{thing=blah}>
Or possibly even just
Test{thing=blah}
I know that I could add a method called inspect()
to all my Java classes, but it seems like every single implementation is just going to call toString()
anyway, because the intent of toString()
in Java is usually the same as the intent of #inspect
in Ruby anyway (i.e., a string only intended to be seen by developers).
So what I'm wondering is, is there a straightforward way to tell JRuby to use toString()
when #inspect
is called on any Java object?
Upvotes: 2
Views: 428
Reputation: 1296
Well, in any other ruby implementation we would just monkey patch the Object#inspect
method, but that is not possible for Java classes because their implementation is native. But you could do something like this to make your life easier:
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>"
The you just have to include your module into the classes you want. If you are really into it you can even create a wrapper around java_import
.
Please, note that I don't recommend monkey patching Object
, or creating any wrappers like this for production code, however in development this can be really useful, and in some cases after careful consideration it might even be used in production.
Upvotes: 1