В мире уже слишком много хаоса, чтобы позволить кому-то решить, что его класс не возвращает строку, когда вы звоните to_s
.Интерпретатор применяет это, вызывая Object#to_s
вместо этого, если ваша реализация возвращает не строковую (или испорченную строку).
Из исходного кода, отредактированного для удобства чтения:
VALUE rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
/* ... */
for (i=0; i<argc; i++) {
/* ... */
line = rb_obj_as_string(argv[i]);
/* outputting line here... */
}
return Qnil;
}
VALUE rb_obj_as_string(VALUE obj)
{
VALUE str;
// if obj is already a String, return it
if (RB_TYPE_P(obj, T_STRING)) {
return obj;
}
// call obj.to_s
str = rb_funcall(obj, idTo_s, 0);
// ensure it is a string
return rb_obj_as_string_result(str, obj);
}
VALUE rb_obj_as_string_result(VALUE str, VALUE obj)
{
// if str isn't a String use Object#to_s
if (!RB_TYPE_P(str, T_STRING)) return rb_any_to_s(obj);
/* ... */
return str;
}