New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rb_check_convert_type compatibility with MRI #2862
Changes from 2 commits
9140537
3b3504e
d171881
f3c9def
e7174db
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -118,24 +118,45 @@ extern "C" { | |
return rb_funcall(env->get_handle(env->state()->globals().type.get()), rb_intern("try_convert"), 3, object_handle, rb_cString, rb_intern("to_str")); | ||
} | ||
|
||
VALUE rb_check_convert_type(VALUE object_handle, int /*type*/, | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use the following multi-line /* this is a comment
* that spans multiple lines
*/ |
||
NOTE: when `0` is given as the `type` no error will be raised. This is due to | ||
the way this function is used in Rbx itself and Rbx not having MRI's | ||
`convert_type` function. | ||
*/ | ||
VALUE rb_check_convert_type(VALUE object_handle, int type, | ||
const char* type_name, const char* method_name) | ||
{ | ||
NativeMethodEnvironment* env = NativeMethodEnvironment::get(); | ||
VALUE name = env->get_handle(String::create(env->state(), method_name)); | ||
VALUE retval = Qnil; | ||
|
||
if(RTEST(rb_funcall(object_handle, rb_intern("respond_to?"), 1, name)) ) { | ||
return rb_funcall2(object_handle, rb_intern(method_name), 0, NULL); | ||
retval = rb_funcall2(object_handle, rb_intern(method_name), 0, NULL); | ||
} | ||
|
||
return Qnil; | ||
// If the method returns nil we can bail out right away. | ||
if ( NIL_P(retval) ) return retval; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if(NIL_P(retval)) |
||
|
||
/* | ||
When the coercion method exists but returns a different type than specified | ||
in `type` MRI will raise an error. This code is mostly a copy-paste job | ||
from the MRI source code. | ||
*/ | ||
if ( type != -1 && TYPE(retval) != type ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same |
||
const char *cname = rb_obj_classname(object_handle); | ||
|
||
rb_raise(rb_eTypeError, "can't convert %s to %s (%s#%s gives %s)", | ||
cname, type_name, cname, method_name, rb_obj_classname(retval)); | ||
} | ||
|
||
return retval; | ||
} | ||
|
||
VALUE rb_check_to_integer(VALUE object_handle, const char *method_name) { | ||
if(FIXNUM_P(object_handle)) { | ||
return object_handle; | ||
} | ||
VALUE result = rb_check_convert_type(object_handle, 0, "Integer", method_name); | ||
VALUE result = rb_check_convert_type(object_handle, -1, "Integer", method_name); | ||
if(rb_obj_is_kind_of(result, rb_cInteger)) { | ||
return result; | ||
} | ||
|
@@ -375,7 +396,7 @@ extern "C" { | |
} | ||
|
||
VALUE rb_to_int(VALUE object_handle) { | ||
return rb_convert_type(object_handle, 0, "Integer", "to_int"); | ||
return rb_convert_type(object_handle, -1, "Integer", "to_int"); | ||
} | ||
|
||
VALUE rb_hash(VALUE obj) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always include the exception name in the spec description.