Feature #14111 » add_receiver_and_method_name_to_argument_error_for_application_code.diff
spec/ruby/core/exception/arguments_spec.rb | ||
---|---|---|
require File.expand_path('../../../spec_helper', __FILE__)
|
||
describe "ArgumentError" do
|
||
class ArgumentErrorDummyClass
|
||
def foo(a,b,c:)
|
||
end
|
||
end
|
||
it "is a subclass of StandardError" do
|
||
StandardError.should be_ancestor_of(ArgumentError)
|
||
end
|
||
... | ... | |
it "gives its own class name as message if it has no message" do
|
||
ArgumentError.new.message.should == "ArgumentError"
|
||
end
|
||
it "includes receiver and method name when raised by application code" do
|
||
exc = begin
|
||
ArgumentErrorDummyClass.new.foo(3)
|
||
rescue => exc
|
||
exc
|
||
end
|
||
exc.instance_variable_get('@receiver').should_not be_nil
|
||
exc.instance_variable_get('@receiver').should.class === ArgumentErrorDummyClass
|
||
exc.instance_variable_get('@method_name').should == 'foo'
|
||
end
|
||
end
|
vm_args.c | ||
---|---|---|
**********************************************************************/
|
||
NORETURN(static void raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VALUE exc));
|
||
NORETURN(static void argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc));
|
||
NORETURN(static void argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_calling_info *calling, const int miss_argc, const int min_argc, const int max_argc));
|
||
NORETURN(static void argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const char *error, const VALUE keys));
|
||
VALUE rb_keyword_error_new(const char *error, VALUE keys); /* class.c */
|
||
static VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv,
|
||
... | ... | |
args_extend(args, min_argc);
|
||
}
|
||
else {
|
||
argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
|
||
argument_arity_error(ec, iseq, calling, given_argc, min_argc, max_argc);
|
||
}
|
||
}
|
||
}
|
||
... | ... | |
given_argc = max_argc;
|
||
}
|
||
else {
|
||
argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
|
||
}
|
||
argument_arity_error(ec, iseq, calling, given_argc, min_argc, max_argc);
|
||
}
|
||
}
|
||
if (iseq->body->param.flags.has_lead) {
|
||
... | ... | |
}
|
||
static void
|
||
argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc)
|
||
argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq,
|
||
struct rb_calling_info *calling,
|
||
const int miss_argc, const int min_argc, const int max_argc)
|
||
{
|
||
VALUE exc = rb_arity_error_new(miss_argc, min_argc, max_argc);
|
||
if (iseq->body->param.flags.has_kw) {
|
||
... | ... | |
RSTRING_PTR(mesg)[RSTRING_LEN(mesg)-1] = ')';
|
||
}
|
||
}
|
||
rb_iv_set(exc, "@receiver", calling->recv);
|
||
rb_iv_set(exc, "@method_name", rb_iseq_method_name(iseq));
|
||
raise_argument_error(ec, iseq, exc);
|
||
}
|
||
vm_insnhelper.c | ||
---|---|---|
CALLER_SETUP_ARG(cfp, calling, ci); /* splat arg */
|
||
if (calling->argc != iseq->body->param.lead_num) {
|
||
argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
|
||
argument_arity_error(ec, iseq, calling, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
|
||
}
|
||
CI_SET_FASTPATH(cc, vm_call_iseq_setup_func(ci, param_size, local_size),
|
||
... | ... | |
}
|
||
}
|
||
else {
|
||
argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
|
||
argument_arity_error(ec, iseq, calling, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
|
||
}
|
||
}
|
||