ext/ox/dump.c in ox-1.2.9 vs ext/ox/dump.c in ox-1.2.10

- old
+ new

@@ -445,11 +445,11 @@ } else { e.indent = depth * out->indent; } e.id = 0; e.clas.len = 0; - e.clas.str = 0; + e.clas.str = 0; switch (rb_type(obj)) { case RUBY_T_NIL: e.type = NilClassCode; e.closed = 1; out->w_start(out, &e); @@ -596,12 +596,11 @@ out->w_time(out, obj); e.indent = -1; out->w_end(out, &e); } else { if (StrictEffort == out->opts->effort) { - rb_raise(rb_eNotImpError, "Failed to dump RUBY_T_DATA %s Object (%02x)\n", - rb_class2name(clas), rb_type(obj)); + rb_raise(rb_eNotImpError, "Failed to dump RUBY_T_DATA %s\n", rb_class2name(clas)); } else { e.type = NilClassCode; e.closed = 1; out->w_start(out, &e); } @@ -671,11 +670,11 @@ cnt = (int)rb_ivar_count(obj); e.closed = (0 >= cnt); out->w_start(out, &e); if (0 < cnt) { unsigned int od = out->depth; - + out->depth = depth + 1; rb_ivar_foreach(obj, dump_var, (VALUE)out); out->depth = od; out->w_end(out, &e); } @@ -779,11 +778,22 @@ } } static int dump_var(ID key, VALUE value, Out out) { + if (RUBY_T_DATA == rb_type(value) && rb_cTime != rb_obj_class(value)) { + /* There is a secret recipe that keeps Exception mesg attributes as a + * T_DATA until it is needed. StringValue() makes the value needed and + * it is converted to a regular Ruby Object. It might seem reasonable + * to expect that this would be done before calling the foreach + * callback but it isn't. A slight hack fixes the inconsistency. If + * the var is not something that can be represented as a String then + * this will fail. + */ + StringValue(value); + } dump_obj(key, value, out->depth, out); - + return ST_CONTINUE; } static int dump_hash(VALUE key, VALUE value, Out out) {