views:

674

answers:

1

Hi guys.

I'm encoding some data using mochijson2. But I found that it behaves strange on strings as lists.

Example:

mochijson2:encode("foo").

[91,"102",44,"111",44,"111",93]

Where "102", "111", "111" are $f, $o, $o encoded as strings 44 are commas and 91 and 93 are square brakets.

Of course if I output this somewhere I'll get string "[102,111,111]" which is obviously not that what I what.

If i try

mochijson2:encode(<<"foo">>).

[34,<<"foo">>,34]

So I again i get a list of two doublequotes and binary part within which can be translated to binary with list_to_binary/1

Here is the question - why is it so inconsistent. I understand that there is a problem distingushing erlang list that should be encoded as json array and erlang string which should be encoded as json string, but at least can it output binary when i pass it binary?

And the second question: Looks like mochijson outputs everything nice (cause it uses special tuple to designate arrays {array, ...})

mochijson:encode(<<"foo">>).
"\"foo\""

What's the difference between mochijson2 and mochijson? Performance? Unicode handling? Anything else?

Thanks

+3  A: 

My guess is that the decision in mochijson is that it treats a binary as a string, and it treats a list of integers as a list of integers. (Un?)fortunately strings in Erlang are in fact a list of integers.

As a result your "foo", or in other words, your [102,111,111] is translated into text representing "[102,111,111]". In the second case your <<"foo">> string becomes "foo"

Regarding the second question, mochijson seems to always return a string, whereas mochijson2 returns an iodata type. Iodata is basically a recursive list of strings, binaries and iodatas (in fact iolists). If you only intend to send the result "through the wire", it is more efficient to just nest them in a list than convert them to a flat string.

Zed
Thanks for your answer, but still not everything clear.I guess: the second case your <<"foo">> string becomes "foo" isn't true, or [34,<<"foo">>,34] is equivalent to "foo" ?what about utf-8 support in mochijson? when i used mochijson2 i added {utf8, true} option to encoder.
Sergey Sinkovskiy
Try erlang:iolist_to_binary([34,<<"foo">>,34]). 34 is a single " character, <<"foo">> is the three character long string foo (w/o "), and the 34 is another ".
Zed
Regardless that your explanation of iodata there is yet another issue. "foo" is not valid JSON and can't be translated to valid JSON.
Hynek -Pichi- Vychodil
@Hynek: Not sure what you mean. The sole purpose of encoding (or translation) is to convert invalid data structures to valid ones.
Zed