# Ruby/Java strings solved the Ruby way

**URL:** <https://www.ruby-forum.com/t/ruby-java-strings-solved-the-ruby-way/143578>\
**Category:** Ruby\
**Created:** [July 20, 2008, 8:08pm UTC](https://www.ruby-forum.com/t/ruby-java-strings-solved-the-ruby-way/143578 "2008-07-20T20:08:42Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [July 20, 2008, 8:08pm UTC](https://www.ruby-forum.com/t/ruby-java-strings-solved-the-ruby-way/143578/1 "2008-07-20T20:08:42Z")

</div>

Hello all!

I’m posting this here because it seem like a topic better discussed in  
the general Ruby community.

JRuby allows you pretty seamless access to Java libraries through its  
Java integration layer. You can pull in just about any class,  
instantiate objects, call methods, and so on. In order to make this a  
bit easier, in many cases we automatically coerce particular Ruby types  
to their equivalent Java types. For example, Fixnum becomes either boxed  
integral or primitive integral values, Floats become boxed  
floating-point or primitive floating point values, and Strings are  
decoded from byte[] into Java String as UTF-8.

But there’s a problem with this…it adds a bit of overhead in the  
numeric cases, and a _lot_ of overhead in the String case.

Here’s a comparison between calling a method that takes an int and a  
method that takes a String (best times out of five):

with string ‘hello’: 1.068688  
with fixnum 1: 0.563014

And this is a short string. The coercion cost for strings is at least  
O(n).

It’s about String coercion I’m writing.

We’ll never be able to eliminate the coercion cost entirely. Ruby  
Strings are byte[] and it has been a great move for us implementing our  
own String and related classes to use byte[] always. So there’s never  
going to be a straight-through path from a Ruby String to a Java String.  
But I think we can reduce the impact for JRuby users by doing things the  
Ruby way.

Ruby already has a protocol for coercion, via methods like to\_str,  
to\_ary and so on. This allows you to pass e.g. non-Strings to methods  
that act on Strings, and frequently (usually) they’ll coerce and work  
fine. Often, if you want to avoid a coercion hit, you’ll create the  
String ahead of time. And that’s where we can learn from Ruby for Java  
String handling.

So I propose that instead of always decoding incoming Ruby String into a  
Java String when calling a Java method, we introduce a new type–call it  
JString for now–that represents a Java string. When you require in the  
Java integration support, it would add to Ruby String a method  
to\_jstring (or to\_String or hey, toString?). So for calls from Ruby to  
Java, we’d follow Ruby coercion protocols and only accept either JString  
or objects that coerce to JString.

Likewise, coming from Java to Ruby, we wouldn’t automatically coerce;  
we’d return a JString object that implements to\_str. You can then  
usually pass that to String APIs, or just coerce it immediately and go  
on with your business. Since this latter change would break some apps  
that expect Java strings to always be coerced, it would be saved for the  
next major release of JRuby and thoroughly discussed.

I think this model provides the best possible experience when calling  
Java from Ruby but also allow JRuby users to take control of the  
coercion process, either be defining their own to\_jstring methods on  
other types, or by pre-coercing strings they intend to use a lot.

Thoughts?

- Charlie

---

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [July 21, 2008, 9:28pm UTC](https://www.ruby-forum.com/t/ruby-java-strings-solved-the-ruby-way/143578/2 "2008-07-21T21:28:21Z")

</div>

On Sun, Jul 20, 2008 at 1:36 PM, Charles Oliver N.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
[snip]

> that to String APIs, or just coerce it immediately and go on with your  
> business. Since this latter change would break some apps that expect Java  
> strings to always be coerced, it would be saved for the next major release  
> of JRuby and thoroughly discussed.

This sounds like an excellent compromise. I vote for to\_jstring  
because it looks most Ruby-esque.

Jim

---

<div class="post-metadata">

**Author:** ![headius](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/7c8e57/32.png) [@headius](https://www.ruby-forum.com/u/headius)\
**Post date:** [July 21, 2008, 11:13pm UTC](https://www.ruby-forum.com/t/ruby-java-strings-solved-the-ruby-way/143578/3 "2008-07-21T23:13:59Z")

</div>

Jim M. wrote:

> > Likewise, coming from Java to Ruby, we wouldn’t automatically coerce; we’d  
> > return a JString object that implements to\_str. You can then usually pass  
> > that to String APIs, or just coerce it immediately and go on with your  
> > business. Since this latter change would break some apps that expect Java  
> > strings to always be coerced, it would be saved for the next major release  
> > of JRuby and thoroughly discussed.
> 
> This sounds like an excellent compromise. I vote for to\_jstring  
> because it looks most Ruby-esque.

Also up for debate is whether boxed primitives from Java should behave  
the same way, with a JInteger, JFloat, and so on that can coerce to  
Fixnum or Float. But boxed primitives are considerably cheaper to coerce  
than Strings, so it may not be worth it.

- Charlie
