On 11/04/14 16:34, Gordon Sim wrote:
In a modified version of your original code snippet:
message.body = ['Rod', 10000001, {cat: true, donkey: 8}];
how would you indicate that this is a management related message and
that therefore the numbers should always be encoded as a double? (and
what about the boolean?)
That's actually a really interesting question and one that has caused me
a lot of navel gazing as to how to best encode from JavaScript into the
AMQP type system (going the other way is relatively easy - well longs
have some interesting edge cases).
I was as bit torn, for being *explicit* about types I started off
thinking about creating a raft of wrapper/boxing classes such as say
proton.Data.Float, proton.Data.UnsignedInteger etc. etc. ad infinitum
:-) though I'm not thinking that I'll use strings with a "literal" form
instead e.g. {"Rod": "4.0f"} {"Jack": "5ul"} and so on and if I want the
string 4.0f to quote it {"Rod": "'4.0f'"} that seems a reasonable
approach for typed numbers in a loosely typed language and feels perhaps
more natural and idiomatic than say {"Rod": new proton.Data.Float(4.0)}
though clearly the latter is as explicit as it gets, but is looking
closer to Java than JavaScript at that point.
I'd be interested in the thoughts of the group on this - I'm open to offers.
It's possibly more "exciting" when considering what to do by default for
numbers. The "easy and obvious" thing to do would be to take JavaScript
numbers and encode them as double, what I'm currently doing looks like
this (still work in progress) because "easy and obvious" didn't
necessarily translate in my mind to "most useful"
} else if (Data.isNumber(obj)) {
/**
* Encoding JavaScript numbers is surprisingly complex and has
several
* gotchas. The code here tries to do what the author believes
is the
* most intuitive encoding of the native JavaScript Number. It
first
* tries to identify if the number is an integer or floating
point type
* by checking if the number modulo 1 is zero (i.e. if it has a
remainder
* then it's a floating point type, which is encoded here as a
double).
* If the number is an integer type a test is made to check if
it is a
* 32 bit Int value. N.B. JavaScript automagically coerces floating
* point numbers with a zero Fractional Part into an exact
integer so
* numbers like 1.0, 100.0 etc. will be encoded as int or long
here,
* which is unlikely to be what is wanted. There's no easy way
around this
* the two main options are to add a very small fractional
number or to
* represent the number in a String literal e.g. "1.0f",
"1.0d", "1l"
*/
if (obj % 1 === 0) {
console.log(obj + " is Integer Type " + (obj|0));
if (obj === (obj|0)) { // the |0 coerces to a 32 bit value.
// 32 bit integer - encode as an Integer.
console.log(obj + " is Int ");
this['putInteger'](obj);
} else { // Longer than 32 bit - encode as a Long.
console.log(obj + " is Long");
this['putLong'](obj);
}
} else { // Floating point type - encode as a Double
console.log(obj + " is Float Type");
this['putDouble'](obj);
}
}
In other words I check if the number is an "integer like number" by
checking its remainder, if it is integer like I coerce it into a 32 bit
value and if that is the same as the original then it is a real integer
otherwise I encode as a long. Floating point types I encode as doubles.
I think that's mostly what would be "natural" in most peoples minds,
however JavaScript screws with that a bit, so to take your example
message.body = ['Rod', 10000001, {cat: true, donkey: 8}];
Those would be encoded as Integers, but unfortunately
message.body = ['Rod', 10000001.0, {cat: true, donkey: 8.0}];
Would also be encoded as Integers because JavaScript implicitly converts
things that can be exactly represented as integers into integers
internally. So something like this
message.body = ['Rod', "10000001.0", {cat: true, donkey: "8.0"}];
Would be needed to specify integer numbers as doubles if you see what I
mean.
I'm quite torn on all of this, which is why I definitely agreed with
your comment that type systems can complicate things rather :-)
Again I'd be interested in what the community thinks would be the most
useful approach. The JavaScript bindings are coming on quite well in the
branch (currently working on Binary data support). I've still got some
tidying, adding tests and sorting out some wrinkles like the stuff
above, but it's starting to look pretty decent.
Frase
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]