I'm currently checking the possibility of porting a big project from JRuby to Truffle Ruby and have hit a potential deal breaker in that the truffle documentation says Java classes cannot be reopened.
We are using the polyglot
package from the GraalVM library.
Our project uses a proprietary Java map implementation (called GMap) which is used practically everywhere in our ruby code base. JRuby allows the Java class to be extended, which is very useful - not least to hide the strict Java typing.
For example, in Java we might have:
GMap map = new GMap();
map.put("k1","test");
map.put("k2", 123);
String s = map.getStr("k1");
int i = map.getInt("k2");
...
Whereas JRuby lets you add convenience methods to the Java class:
map = GMap.new
map[:key1] = 'test'
map[:key2] = 123
s = map[:key1]
i = map[:key2]
...
...which is much cleaner.
Does anyone know of a way of replicating this behavior in Truffle Ruby?
EDIT:
In reply to aled's comment, here is an example of a JRuby monkey patch which has been modified to use polyglot
syntax:
Java.import 'org.jellyfish.gmap.GMap'
class GMap
def [] (key)
self.__send__(:getObj, [java.lang.String],
key.to_s.to_java(:string))
end
end
end
The second line of code fails with the error:
#<Polyglot::ForeignClass[Java] type org.jellyfish.gmap.GMap> is not a class
To reproduce the error any standard java class can be used.
Does
GMap
implementjava.util.Map
? If so,[]
and[]=
are already automatically defined, as documented here.