Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java types should simply toString on inspect? #5182

Closed
kares opened this issue May 22, 2018 · 9 comments
Closed

Java types should simply toString on inspect? #5182

kares opened this issue May 22, 2018 · 9 comments

Comments

@kares
Copy link
Member

kares commented May 22, 2018

Java types inspect isn't as useful as for Ruby objects.
When using Ruby tools it usually just shows the type but no real information, e.g.

  2) Date"to_java java 8 types coerces to java.time.Instant
     Failure/Error: DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure }

       expected: #<Java::JavaTime::Instant:0x25ce9dc4>
            got: #<Java::JavaTime::Instant:0x17f62e33>

       (compared using ==)

       Diff:
       @@ -1,2 +1,2 @@
       -#<Java::JavaTime::Instant:0x25ce9dc4>
       +#<Java::JavaTime::Instant:0x17f62e33>
     # ./spec/java_integration/types/coercion_spec.rb:946:in `block in (root)'

its likely a breaking change -> so only to be done in a major version such as 9.2

@headius
Copy link
Member

headius commented May 25, 2018

At one point inspect also showed fields, by reflectively digging them out. Once we removed that, the inspect output is now largely useless other than showing what type the object is.

Perhaps it should be something like #<Java::SomeJavaPackage::SomeClass:0xcafebabe "toString output"> I think objections in the past were that the toString for a Java object could be very large, and inspect is often used for logging errors etc.

@kares
Copy link
Member Author

kares commented May 26, 2018

At one point inspect also showed fields, by reflectively digging them out. Once we removed that, the inspect output is now largely useless other than showing what type the object is.

that would make sense for me, but only doing that if there isn't a toString override (which is tricky).
should mean common types such as ArrayList or Java Date will return a simple representation (like in Ruby). large or not, there's giant inspect in Rails e.g. when you inspect a connection or smt holding it.

@headius
Copy link
Member

headius commented Jun 12, 2018

A simple way to do this is to just define java.lang.Object.inspect to call to_s, but that will do it for all Java objects, not just the ones that have overridden to_s.

@headius
Copy link
Member

headius commented Jun 12, 2018

Ok, so I thought I could do a clever trick like this:

class java::lang::Object
  alias old_inspect inspect
  def inspect
    toString
  end
  def toString
    old_inspect
  end
end

There's a couple snags though:

  • I needed to comment out the default to_s impl from JavaProxyMethods.
  • We do not overwrite toString in subclasses that implement it, because we always try to dispatch using the highest implementer (for various reasons, like nonpublic child classes). So this never actually uses the real toString output.

@headius
Copy link
Member

headius commented Jun 12, 2018

Actually ignore that first bullet; I don't think it matters. The main problem is that toString lives on exactly one Java type within JRuby: java.lang.Object. This makes it tricky to only make inspect call toString when overridden by a given class.

@kares
Copy link
Member Author

kares commented Jun 13, 2018

have an idea to play some 'ugly' tricks around and hook this up into the JavaProxy class, as I want it to play well with existing Java array inspect-ing while also providing a reflective default, we'll see how it goes ...

@kares kares self-assigned this Jun 13, 2018
@headius
Copy link
Member

headius commented Jun 13, 2018

Ok I'll let you play with it then.

@kares
Copy link
Member Author

kares commented Jun 14, 2018

some progress - to make it somehow cleaner I would be reverting an old feature, where a proxy Java class does not get instance methods put in if its smt that exists in super hierarchy e.g. an ArrayList has a toString from AbstractCollection but the AbstractCollection.instance_methods won't include :toString since its already there on java.lang.Object ... this 'feature' is way back from fe133a2

kares added a commit to kares/jruby that referenced this issue Jun 15, 2018
this would be a resolution for weird non-readable rspec output
... with Java types - jrubyGH-5182
kares added a commit that referenced this issue Jun 15, 2018
this would be a resolution for weird non-readable rspec output
... with Java types - GH-5182
kares added a commit that referenced this issue Jun 15, 2018
this would be a resolution for weird non-readable rspec output
... with Java types - GH-5182
kares added a commit that referenced this issue Sep 11, 2018
this would be a resolution for weird non-readable rspec output
... with Java types - GH-5182
@kares
Copy link
Member Author

kares commented Oct 23, 2018

JRuby will be shipping changed Java type inspect -> toString in 9.2.1 (#5219)

@kares kares closed this as completed Oct 23, 2018
@kares kares added this to the JRuby 9.2.1.0 milestone Oct 23, 2018
kares added a commit to kares/jruby that referenced this issue Jun 20, 2019
this would be a resolution for weird non-readable rspec output
... with Java types - jrubyGH-5182
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants