Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

BigDecimal encoded differently in compat mode #64

Closed
wants to merge 1 commit into from

2 participants

@rolftimmermans

In compat mode, BigDecimals are encoded as strings. In other modes, they are numbers. This is probably a mistake, because the correct code appears to be accidenatlly commented out in 7a573f2.

This PR reverts it and fixes the problem.

Oj.dump(BigDecimal.new("7"), mode: :strict)
=> 0.7E1
Oj.dump(BigDecimal.new("7"), mode: :object)
=> 0.7E1
Oj.dump(BigDecimal.new("7"), mode: :compat)
=> "0.7E1"
@ohler55
Owner

The code is correct as it is. Compat mode is meant to be compatible with other parsers and sadly they do not handle larger numbers. This use of strings was done in a fairly recent release due to complaints that it broke other parsers. If you have a good use case where the value should be a number instead of a string I can consider other options for supporting both opinions.

@rolftimmermans

Thanks for your answer. I didn't expect the behaviour was intentional.

I have some BigDecimals that come from an outside source and I want to serialise them as JS numbers, not strings. Also, I want to use MultiJson which pretty much forces me to use compat mode (possibly a good thing). I thought fixing the behaviour of compat mode with respect to BigDecimals was the way to go.

As I understand it isn't really, so now that I'm trying to override this behaviour, I'm trying to use to_json instead:

class BigDecimal
  def to_json
    "foo"
  end
end

Oj.dump(BigDecimal.new("7"), mode: :compat)
# => "0.7E1"

Does to_json not get called for BigDecimals?

@ohler55
Owner

I could add an option to output BigNumbers as either digits or a string. Would that work for you.

You are right, BigNumbers are handled differently since under the covers in most Ruby implementations they are not regular objects but rather special data structures. Oj should check for to_json() in compat mode. I will mark that as a bug and get it fixed in a future release.

@rolftimmermans

An option would definitely work -- a call to to_json would also be sufficient in my particular situation. Either works for me. Thanks for your swift responses. I appreciate your work on Oj!

@ohler55
Owner

Thanks. I will do both.

@sferik sferik referenced this pull request in intridea/multi_json
Closed

Inconsistant serialization of BigDecimal instances #80

@ohler55 ohler55 closed this
@ohler55
Owner

I create 2 issues to to track the feature requests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 6, 2013
  1. @rolftimmermans
This page is out of date. Refresh to see the latest.
Showing with 1 addition and 2 deletions.
  1. +1 −2  ext/oj/dump.c
View
3  ext/oj/dump.c
@@ -1194,8 +1194,7 @@ dump_obj_comp(VALUE obj, int depth, Out out) {
if (oj_bigdecimal_class == clas) {
VALUE rstr = rb_funcall(obj, oj_to_s_id, 0);
- //dump_raw(StringValuePtr(rstr), RSTRING_LEN(rstr), out);
- dump_cstr(StringValuePtr(rstr), RSTRING_LEN(rstr), 0, 0, out);
+ dump_raw(StringValuePtr(rstr), RSTRING_LEN(rstr), out);
} else {
Odd odd = oj_get_odd(clas);
Something went wrong with that request. Please try again.