Skip to content
Browse files

* JRUBY-6785 Make the receiver for callMethod more consistent

* Allow nil as a receiver
* Allow Java objects as receivers.  These will be wrapped before use.
  • Loading branch information...
1 parent a90bb11 commit 7c8dba153bc41fa8b2795fe0ccfb682d0818e3be @donv donv committed with Jul 25, 2012
View
4 src/org/jruby/embed/ScriptingContainer.java
@@ -1766,4 +1766,8 @@ public void finalize() throws Throwable {
super.finalize();
terminate();
}
+
+ public IRubyObject getTopSelf() {
+ return getProvider().getRuntime().getTopSelf();
+ }
}
View
4 src/org/jruby/embed/jsr223/JRubyEngine.java
@@ -256,9 +256,9 @@ public Object invokeFunction(String method, Object... args)
try {
Utils.preEval(container, context);
if (args == null || args.length == 0) {
- return container.callMethod(null, method, Object.class);
+ return container.callMethod(container.getTopSelf(), method, Object.class);
}
- return container.callMethod(null, method, args, Object.class);
+ return container.callMethod(container.getTopSelf(), method, args, Object.class);
} catch (Exception e) {
if (e.getCause().getMessage().contains("undefined method")) {
throw wrapMethodException(e);
View
52 test/org/jruby/embed/ScriptingContainerTest.java
@@ -926,9 +926,9 @@ public void testCallMethod_3args() {
receiver = instance.runScriptlet(script);
instance.put("@r", 1.0);
instance.put("@h", Math.sqrt(3.0));
- double volume = instance.callMethod(receiver, "volume", Double.class);
+ double volume = instance.callMethod(instance.getTopSelf(), "volume", Double.class);
assertEquals(1.813799, volume, 0.000001);
- double surface_area = instance.callMethod(receiver, "surface_area", Double.class);
+ double surface_area = instance.callMethod(instance.getTopSelf(), "surface_area", Double.class);
assertEquals(9.424778, surface_area, 0.000001);
instance.getVarMap().clear();
@@ -1037,8 +1037,6 @@ public void testCallMethod_4args_3() {
// Sharing local variables over method call doesn't work.
// Should delete methods with unit argument?
logger1.info("callMethod(receiver, methodName, returnType, unit)");
- Object receiver = null;
- String methodName = "";
Class<Object> returnType = null;
EmbedEvalUnit unit = null;
ScriptingContainer instance = new ScriptingContainer(LocalContextScope.THREADSAFE, LocalVariableBehavior.PERSISTENT);
@@ -1048,9 +1046,9 @@ public void testCallMethod_4args_3() {
instance.setWriter(writer);
instance.setErrorWriter(writer);
- Object expResult = null;
- Object result = instance.callMethod(receiver, methodName, returnType, unit);
- assertEquals(expResult, result);
+ // Verify that empty message name returns null
+ Object result = instance.callMethod(null, "", returnType, unit);
+ assertEquals(null, result);
String text =
"songs:\n"+
@@ -1060,17 +1058,18 @@ public void testCallMethod_4args_3() {
"podcasts:\n" +
"- Java Posse\n" +
"- Stack Overflow";
- String filename = "org/jruby/embed/ruby/yaml_dump.rb";
StringWriter sw = new StringWriter();
instance.setWriter(sw);
// local variable doesn't work in this case, so instance variable is used.
instance.put("@text", text);
- unit = instance.parse(PathType.CLASSPATH, filename);
- receiver = unit.run();
- methodName = "dump";
- result = instance.callMethod(receiver, methodName, null, unit);
- expResult =
- "songs: Hey Soul Sister, Who Says, Apologize\npodcasts: Java Posse, Stack Overflow\n";
+ unit = instance.parse(PathType.CLASSPATH, "org/jruby/embed/ruby/yaml_dump.rb");
+ Object receiver = unit.run();
+ IRubyObject nil = instance.getProvider().getRuntime().getNil();
+ assertSame(nil, receiver);
+ IRubyObject topSelf = instance.getProvider().getRuntime().getTopSelf();
+ result = instance.callMethod(topSelf, "dump", null, unit);
+ Object expResult =
+ "songs: Hey Soul Sister, Who Says, Apologize\npodcasts: Java Posse, Stack Overflow\n";
assertEquals(expResult, sw.toString());
instance.getVarMap().clear();
@@ -1124,6 +1123,29 @@ public void testCallMethod_without_returnType() {
assertEquals(expList, list);
}
+ @Test
+ public void test_CallMethod_with_non_ruby_receiver() {
+ logger1.info("callMethod no returnType");
+ ScriptingContainer instance = new ScriptingContainer(LocalContextScope.THREADSAFE);
+ instance.setError(pstream);
+ instance.setOutput(pstream);
+ instance.setWriter(writer);
+ instance.setErrorWriter(writer);
+ assertEquals(true, instance.callMethod(null, "nil?"));
+ assertEquals(true, instance.callMethod(instance.getProvider().getRuntime().getNil(), "nil?"));
+ assertEquals(false, instance.callMethod("A Java String", "nil?"));
+ String script =
+ "ScriptingContainer = Java::org.jruby.embed.ScriptingContainer\n" +
+ "class ScriptingContainer\n" +
+ "def say_something\n" +
+ "'Something'\n" +
+ "end\n" +
+ "end\n";
+ instance.runScriptlet(script);
+ String something = (String)instance.callMethod(instance, "say_something");
+ assertEquals("Something", something);
+ }
+
/**
* Test of callMethod method, of class ScriptingContainer.
*/
@@ -2727,4 +2749,4 @@ public void testExitTerminatesScript() {
Object result = instance.runScriptlet("exit 1234");
assertEquals(1234L, result);
}
-}
+}

0 comments on commit 7c8dba1

Please sign in to comment.
Something went wrong with that request. Please try again.