Add all Ruby Hash methods to a Java Map by "add_ruby_methods" -------------------------------------------------------------
Key: JRUBY-4528 URL: http://jira.codehaus.org/browse/JRUBY-4528 Project: JRuby Issue Type: Wish Components: Java Integration Affects Versions: JRuby 1.5 Reporter: Yoko Harada Attachments: add_ruby_methods.patch, AddHashMethodsToMap.java Attached patch enables to use "add_ruby_methods" method to proxied all Java Map type objects. The new method adds all Ruby Hash methods to a Map type object. This patch and the new method will resolve the filed bug, JRUBY-4223, and alters my proposal, JRUBY-4314. With this new method, we can directly manipulate Java Map objects, which is useful especially for embedders. For example, we can use merge! method against ConcurrentHashMap as in below: {noformat} ScriptingContainer container = new ScriptingContainer(LocalContextScope.SINGLETHREAD); ConcurrentHashMap map1 = new ConcurrentHashMap(); map1.put("a", 100); map1.put("b", 200); Map map2 = new HashMap(); map2.put("b", 254); map2.put("c", 300); container.put("h1", map1); container.put("h2", map2); container.put("num", 0); String script = "rh = h1.add_ruby_methods\n" + "puts \"num: #{num}\"\n" + "rh.merge!(h2.add_ruby_methods) {|k,o,n| num += 1; o+n }"; container.runScriptlet(script); Set<Map.Entry> entries = map1.entrySet(); for (Map.Entry entry : entries) { System.out.print(entry.getKey() + ": " + entry.getValue() + ", "); } {noformat} The code produces values in ConcurrentHashMap: {noformat} b: 454, a: 100, c: 300, {noformat} Also, we can use the add_ruby_methods method on interpreter: {noformat} irb(main):004:0> require 'java' => true irb(main):005:0> jhash = java.util.HashMap.new => {} irb(main):006:0> jhash.put("1", 100) => nil irb(main):007:0> jhash.put("2", 200) => nil irb(main):008:0> jhash.inspect => "{2=200, 1=100}" irb(main):009:0> rhash = jhash.add_ruby_methods => {"2"=>200, "1"=>100} irb(main):010:0> rhash.inspect => "{\"2\"=>200, \"1\"=>100}" irb(main):011:0> p rhash.values [200, 100] => nil irb(main):012:0> rhash.merge!({"2"=>222, "3"=>333}) => {"3"=>333, "2"=>222, "1"=>100} irb(main):013:0> jhash.inspect => "{3=333, 2=222, 1=100}" {noformat} To make this happen, I made small changes on org.jruby.RubyHash so that other class can override some methods. Tentatively, JavaHash class is located under org.jruby.embed.ji package, but probably, org.jruby.javasupport might be a better place since we can also apply the method to a Java object created in Ruby code. -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://jira.codehaus.org/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email