Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions core/src/main/java/org/jruby/embed/EmbedRubyObjectAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
*/
package org.jruby.embed;

import java.util.Map;

import org.jruby.RubyObjectAdapter;
import org.jruby.runtime.Block;

Expand Down Expand Up @@ -184,4 +186,108 @@ public interface EmbedRubyObjectAdapter extends RubyObjectAdapter {
* @return an instance of requested Java type
*/
<T> T runRubyMethod(Class<T> returnType, Object receiver, String methodName, Block block, Object... args);

/**
* Executes a method defined in Ruby script, passing keyword arguments only.
* <p>
* Each map key is treated as a kwarg name and resolved to a Ruby
* {@code Symbol}. The accepted key types are {@link RubySymbol} (used
* directly), {@link String}, and {@link org.jruby.RubyString}
* (both converted via {@code toString()} + {@code newSymbol(...)}). Any
* other key type causes an {@link IllegalArgumentException}. Values are
* converted from Java to Ruby via the standard JavaEmbedUtils conversions.
* A {@code null} or empty {@code kwargs} map results in a call with no
* keyword arguments.
*
* @param receiver is an instance that will receive this method call
* @param methodName is a method name to be called
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @return an instance automatically converted from Ruby to Java
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* implementation is configured to wrap exceptions.
* @since JRuby 10.1.2.0
*/
Object callMethodWithKeywordArgs(Object receiver, String methodName, Map<?, Object> kwargs);
Comment thread
drzaiusx11 marked this conversation as resolved.

/**
* Executes a method defined in Ruby script, passing positional and keyword arguments.
* <p>
* See {@link #callMethodWithKeywordArgs(Object, String, Map)} for details on how
* kwarg keys and values are converted.
*
* @param receiver is an instance that will receive this method call
* @param methodName is a method name to be called
* @param args is an array of positional method arguments. May be
* {@code null} or empty to indicate no positional arguments.
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @return an instance automatically converted from Ruby to Java
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* implementation is configured to wrap exceptions.
* @since JRuby 10.1.2.0
*/
Object callMethodWithKeywordArgs(Object receiver, String methodName, Object[] args, Map<?, Object> kwargs);

/**
* Executes a method defined in Ruby script, passing positional and keyword arguments,
* and converts the result to the given Java type.
* <p>
* See {@link #callMethodWithKeywordArgs(Object, String, Map)} for details on how
* kwarg keys and values are converted.
*
* @param receiver is an instance that will receive this method call
* @param methodName is a method name to be called
* @param args is an array of positional method arguments. May be
* {@code null} or empty to indicate no positional arguments.
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @param returnType is the Java type to convert the return value to. Pass
* {@code null} to discard the result and return {@code null}.
* @param <T> the Java type to convert the return value to
* @return an instance of the requested Java type, or {@code null} if
* {@code returnType} is {@code null}
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* implementation is configured to wrap exceptions.
* @since JRuby 10.1.2.0
*/
<T> T callMethodWithKeywordArgs(Object receiver, String methodName, Object[] args, Map<?, Object> kwargs, Class<T> returnType);

/**
* Executes a method defined in Ruby script, passing positional args, keyword
* args, and a block, and converts the result to the given Java type.
* <p>
* Pass {@link org.jruby.runtime.Block#NULL_BLOCK} for {@code block} to
* indicate "no block" — equivalent to a Ruby call without a block (any
* {@code yield} in the callee will raise {@code LocalJumpError} unless
* guarded by {@code block_given?}). See
* {@link #callMethodWithKeywordArgs(Object, String, Map)} for details on how
* kwarg keys and values are converted.
*
* @param receiver is an instance that will receive this method call
* @param methodName is a method name to be called
* @param args is an array of positional method arguments. May be
* {@code null} or empty to indicate no positional arguments.
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @param block is a block to be executed in this method, or
* {@link org.jruby.runtime.Block#NULL_BLOCK} for no block.
* @param returnType is the Java type to convert the return value to. Pass
* {@code null} to discard the result and return {@code null}.
* @param <T> the Java type to convert the return value to
* @return an instance of the requested Java type, or {@code null} if
* {@code returnType} is {@code null}
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* implementation is configured to wrap exceptions.
* @since JRuby 10.1.2.0
*/
<T> T callMethodWithKeywordArgs(Object receiver, String methodName, Object[] args, Map<?, Object> kwargs, Block block, Class<T> returnType);
}
138 changes: 138 additions & 0 deletions core/src/main/java/org/jruby/embed/ScriptingContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import org.jruby.RubyGlobal.InputGlobalVariable;
import org.jruby.RubyGlobal.OutputGlobalVariable;
import org.jruby.RubyIO;
import org.jruby.RubySymbol;
import org.jruby.RubyInstanceConfig.CompileMode;
import org.jruby.RubyInstanceConfig.LoadServiceCreator;
import org.jruby.RubyInstanceConfig.ProfilingMode;
Expand Down Expand Up @@ -1504,6 +1505,143 @@ public <T> T callMethod(Object receiver, String methodName, Object[] args, Block
return objectAdapter.callMethod(receiver, methodName, args, block, returnType, unit);
}

/**
* Executes a method defined in Ruby script, passing keyword arguments only.
* <p>
* Use this overload when the target Ruby method declares only keyword
* parameters (e.g. {@code def greet(name:, greeting: 'Hello')}). Each map
* key is treated as a kwarg name and resolved to a Ruby {@code Symbol}.
* The accepted key types are {@link RubySymbol} (used directly),
* {@link String}, and {@link org.jruby.RubyString} (both converted via
* {@code toString()} + {@code newSymbol(...)}). Any other key type causes
* an {@link IllegalArgumentException}. Values are converted from Java to
* Ruby via the standard JavaEmbedUtils conversions. A {@code null} or
* empty {@code kwargs} map results in a call with no keyword arguments.
*
* <pre>Example
* ScriptingContainer container = new ScriptingContainer();
* Object receiver = container.runScriptlet(
* "def greet(name:, greeting: 'Hello')\n" +
* " \"#{greeting}, #{name}!\"\n" +
* "end\n" +
* "self");
*
* Map&lt;String, Object&gt; kwargs = new HashMap&lt;&gt;();
* kwargs.put("name", "World");
* Object result = container.callMethodWithKeywordArgs(receiver, "greet", kwargs);
* // result == "Hello, World!"</pre>
*
* @param receiver is an instance that will receive this method call.
* Ruby's self object will be used if no appropriate receiver
* is given.
* @param methodName is a method name to be called
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @return an instance automatically converted from Ruby to Java
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* container is configured to wrap exceptions (the default).
* @since JRuby 10.1.1.0
*/
public Object callMethodWithKeywordArgs(Object receiver, String methodName, Map<?, Object> kwargs) {
return objectAdapter.callMethodWithKeywordArgs(receiver, methodName, kwargs);
}

/**
* Executes a method defined in Ruby script, passing positional and keyword arguments.
* <p>
* Use this overload when the target Ruby method declares both positional
* parameters and keyword parameters (e.g.
* {@code def combine(a, b, separator: ', ')}). See
* {@link #callMethodWithKeywordArgs(Object, String, Map)} for details on
* how kwarg keys and values are converted.
*
* @param receiver is an instance that will receive this method call.
* Ruby's self object will be used if no appropriate receiver
* is given.
* @param methodName is a method name to be called
* @param args is an array of positional method arguments. May be
* {@code null} or empty to indicate no positional arguments.
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @return an instance automatically converted from Ruby to Java
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* container is configured to wrap exceptions (the default).
* @since JRuby 10.1.1.0
*/
public Object callMethodWithKeywordArgs(Object receiver, String methodName, Object[] args, Map<?, Object> kwargs) {
return objectAdapter.callMethodWithKeywordArgs(receiver, methodName, args, kwargs);
}

/**
* Executes a method defined in Ruby script, passing positional and keyword arguments,
* and converts the result to the given Java type.
* <p>
* See {@link #callMethodWithKeywordArgs(Object, String, Map)} for details
* on how kwarg keys and values are converted.
*
* @param receiver is an instance that will receive this method call.
* Ruby's self object will be used if no appropriate receiver
* is given.
* @param methodName is a method name to be called
* @param args is an array of positional method arguments. May be
* {@code null} or empty to indicate no positional arguments.
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @param returnType is the Java type to convert the return value to. Pass
* {@code null} to discard the result and return {@code null}.
* @param <T> the Java type to convert the return value to
* @return an instance of the requested Java type, or {@code null} if
* {@code returnType} is {@code null}
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* container is configured to wrap exceptions (the default).
* @since JRuby 10.1.1.0
*/
public <T> T callMethodWithKeywordArgs(Object receiver, String methodName, Object[] args, Map<?, Object> kwargs, Class<T> returnType) {
return objectAdapter.callMethodWithKeywordArgs(receiver, methodName, args, kwargs, returnType);
}

/**
* Executes a method defined in Ruby script, passing positional args, keyword
* args, and a block, and converts the result to the given Java type.
* <p>
* Pass {@link org.jruby.runtime.Block#NULL_BLOCK} for {@code block} to
* indicate "no block" — equivalent to a Ruby call without a block (any
* {@code yield} in the callee will raise {@code LocalJumpError} unless
* guarded by {@code block_given?}). See
* {@link #callMethodWithKeywordArgs(Object, String, Map)} for details on
* how kwarg keys and values are converted.
*
* @param receiver is an instance that will receive this method call.
* Ruby's self object will be used if no appropriate receiver
* is given.
* @param methodName is a method name to be called
* @param args is an array of positional method arguments. May be
* {@code null} or empty to indicate no positional arguments.
* @param kwargs is a map of keyword argument names to values. Keys must be
* {@code String}, {@code RubyString}, or {@code RubySymbol}.
* May be {@code null} or empty to indicate no keyword arguments.
* @param block is a block to be executed in this method, or
* {@link org.jruby.runtime.Block#NULL_BLOCK} for no block.
* @param returnType is the Java type to convert the return value to. Pass
* {@code null} to discard the result and return {@code null}.
* @param <T> the Java type to convert the return value to
* @return an instance of the requested Java type, or {@code null} if
* {@code returnType} is {@code null}
* @throws IllegalArgumentException if a key is not a supported type
* @throws InvokeFailedException if the underlying Ruby call raises and the
* container is configured to wrap exceptions (the default).
* @since JRuby 10.1.1.0
*/
public <T> T callMethodWithKeywordArgs(Object receiver, String methodName, Object[] args, Map<?, Object> kwargs, Block block, Class<T> returnType) {
return objectAdapter.callMethodWithKeywordArgs(receiver, methodName, args, kwargs, block, returnType);
}

/**
*
* @param receiver is an instance that will receive this method call.
Expand Down
Loading
Loading