coerce.patch
numeric.c  

211  211 
return rb_assoc_new(y, x); 
212  212 
} 
213  213  
214 
static VALUE 

215 
coerce_body(VALUE *x) 

216 
{ 

217 
return rb_funcall(x[1], id_coerce, 1, x[0]); 

218 
} 

219  
220 
static VALUE 

221 
coerce_rescue(VALUE *x) 

222 
{ 

223 
volatile VALUE v = rb_inspect(x[1]); 

224  
225 
rb_raise(rb_eTypeError, "%s can't be coerced into %s", 

226 
rb_special_const_p(x[1])? 

227 
RSTRING_PTR(v): 

228 
rb_obj_classname(x[1]), 

229 
rb_obj_classname(x[0])); 

230 
return Qnil; /* dummy */ 

231 
} 

232  
233  214 
static int 
234  215 
do_coerce(VALUE *x, VALUE *y, int err) 
235  216 
{ 
236  217 
VALUE ary; 
237 
VALUE a[2]; 

238  
239 
a[0] = *x; a[1] = *y; 

240  218  
241 
ary = rb_rescue(coerce_body, (VALUE)a, err?coerce_rescue:0, (VALUE)a); 

242 
if (!RB_TYPE_P(ary, T_ARRAY)  RARRAY_LEN(ary) != 2) { 

219 
ary = rb_check_funcall(*y, id_coerce, 1, x); 

220 
if (ary == Qundef && err) { 

221 
volatile VALUE v = rb_inspect(*y); 

222 
rb_raise(rb_eTypeError, "%s can't be coerced into %s", 

223 
rb_special_const_p(*y)? 

224 
RSTRING_PTR(v): 

225 
rb_obj_classname(*y), 

226 
rb_obj_classname(*x)); 

227 
return FALSE; /* dummy */ 

228 
} 

229 
if (ary == Qundef  !RB_TYPE_P(ary, T_ARRAY)  RARRAY_LEN(ary) != 2) { 

243  230 
if (err) { 
244  231 
rb_raise(rb_eTypeError, "coerce must return [x, y]"); 
245  232 
} 