Skip to content

Commit 0c1fa51

Browse files
committed
Impl KeyError.initialize with receiver and key kwargs
https://bugs.ruby-lang.org/issues/14313 See #5576
1 parent 6fe36b9 commit 0c1fa51

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

core/src/main/java/org/jruby/RubyKeyError.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,18 @@
3333

3434
import org.jruby.anno.JRubyMethod;
3535
import org.jruby.anno.JRubyClass;
36+
import org.jruby.ast.util.ArgsUtil;
3637
import org.jruby.exceptions.KeyError;
3738
import org.jruby.exceptions.RaiseException;
39+
import org.jruby.runtime.ThreadContext;
3840
import org.jruby.runtime.builtin.IRubyObject;
3941

4042
/**
4143
* @author Miguel Landaeta
4244
*/
4345
@JRubyClass(name="KeyError", parent="IndexError")
4446
public class RubyKeyError extends RubyIndexError {
47+
private static final String[] VALID_KEYS = {"receiver", "key"};
4548
private IRubyObject receiver;
4649
private IRubyObject key;
4750

@@ -67,6 +70,49 @@ protected RaiseException constructThrowable(String message) {
6770
return new KeyError(message, this);
6871
}
6972

73+
@JRubyMethod
74+
public IRubyObject initialize(ThreadContext context, IRubyObject messageOrKwargs) {
75+
IRubyObject[] receiverKey = ArgsUtil.extractKeywordArgs(context, messageOrKwargs, VALID_KEYS);
76+
77+
if (receiverKey == null) return initialize(context, messageOrKwargs, null);
78+
79+
return initializeCommon(context, context.nil, receiverKey);
80+
}
81+
82+
@JRubyMethod
83+
public IRubyObject initialize(ThreadContext context, IRubyObject message, IRubyObject kwargs) {
84+
IRubyObject[] receiverKey = ArgsUtil.extractKeywordArgs(context, kwargs, VALID_KEYS);
85+
86+
return initializeCommon(context, message, receiverKey);
87+
}
88+
89+
private IRubyObject initializeCommon(ThreadContext context, IRubyObject message, IRubyObject[] receiverKey) {
90+
IRubyObject receiver;
91+
IRubyObject key;
92+
if (receiverKey == null) {
93+
receiver = context.nil;
94+
key = context.nil;
95+
} else {
96+
receiver = receiverKey[0];
97+
key = receiverKey[1];
98+
}
99+
100+
setMessage(message);
101+
this.receiver = receiver;
102+
this.key = key;
103+
104+
return context.nil;
105+
}
106+
107+
@JRubyMethod
108+
public IRubyObject initialize(ThreadContext context, IRubyObject message, IRubyObject receiver, IRubyObject key) {
109+
setMessage(message);
110+
this.receiver = receiver;
111+
this.key = key;
112+
113+
return context.nil;
114+
}
115+
70116
@JRubyMethod
71117
public IRubyObject receiver() {
72118
return receiver;

core/src/main/java/org/jruby/ast/util/ArgsUtil.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,16 @@ public void visit(IRubyObject key, IRubyObject value) {
145145

146146
// not used
147147
public static IRubyObject[] extractKeywordArgs(ThreadContext context, IRubyObject[] args, String... validKeys) {
148-
IRubyObject options = ArgsUtil.getOptionsArg(context.runtime, args);
148+
return extractKeywordArgs(context, ArgsUtil.getOptionsArg(context.runtime, args), validKeys);
149+
}
150+
151+
public static IRubyObject[] extractKeywordArgs(ThreadContext context, IRubyObject maybeKwargs, String... validKeys) {
152+
IRubyObject options = ArgsUtil.getOptionsArg(context.runtime, maybeKwargs);
153+
149154
if (options instanceof RubyHash) {
150155
return extractKeywordArgs(context, (RubyHash) options, validKeys);
151156
}
157+
152158
return null;
153159
}
154160

0 commit comments

Comments
 (0)