Hakanai
Hakanai

Reputation: 12680

Is there a way to get good `#inspect` output for Java objects in JRuby?

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

Answers (1)

elyalvarado
elyalvarado

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

Related Questions