Hi,

I'm hoping someone here can give me some insight in to what I can do as
I feel sure someone must have hit this problem before. The software I'm
working is a good deal more complex than what is described here but I've
tried to resolve it down to make it more simple (perhaps
unsuccessfully).

The application reads values from a databases (but we'll stick to Oracle
for now), converts the data to JSON (JavaScript Object Notation), writes
the json to a file where it is picked up by some javascript code. JSON
was chosen because JSON is native to javascript and the javascript can
simply eval the read data to turn it into a javascript object.

With DBI/DBD::Oracle all values read from the database are scalars. As
everyone will know, whether something read from the database is a string
or a number in Perl purely depends on the context it is used in so:

$a = "1";
print $a +1 results in 2
and 
print $a . 2 results in 12;

The problem is javascript is more tightly typed than Perl and it matters
whether something is a number or a string - it affects what operations
you can perform on a variable.

In JSON, a string is represented by quotes around it and a number is
missing the quotes.

My problem is that values read from the database which are actually
numbers (in the database) look like strings to the JSON parser so when I
do a selectall_arrayref("select number_field from table") and convert
the result to JSON I get:

["12"] in the serialised JSON data instead of:

[12]

I have to admit I don't know how the JSON module knows what is a number
and what is a string in Perl but I see the same issue with Data::Dumper
so I presume there must be some way to find out if a perl scalar is a
number or a string.
 
The problem gets a lot worse for me since I do some arithmetic on values
pulled from the database before converting them to JSON and this is
where Perl seems to change them into numbers e.g.

$r = selectall_arrayref(select number1, number2 from table);
$r->[0] += 2;
results in JSON output of:

[3, "3"]

and this really annoys javascript since the first value is typed as a
number and the second as a string.

You can imagine this can get really hairy if you have a field in the DB
called house_number_or_name.

Whilst investigating this I tried to reproduce with Data::Dumper
(another data serialiser) but the problem gets even more unfathomable to
me:

perl -MData::Dumper -le '$a = [1,"2"];print Dumper($a);'
$VAR1 = [1,'2'];

so Data::Dumper knows "2" is a string (XS version) and yet:

perl -MData::Dumper -le ' $Data::Dumper::Useperl =1;$a = [1,"2"];print
Dumper($a);'
$VAR1 = [1,2];

just because I've switched to a Perl version of Data::Dumper "2" is a
number.

I don't want to have to do ($var +0) on all the number fields I pull
from the database (to turn them into numbers) and neither do I want to
do a '$var .= ""' (to turn all the fields into strings).

As an aside (and probably a perl question rather than a DBI one) does
anyone know why the type of a scalar changes when you use it on the
right side of an assignment:

perl -MData::Dumper -le '$a="1"; print Dumper($a); $b += $a; print
Dumper($a);'
$VAR1 = '1';
$VAR1 = 1;

How does JSON and Data::Dumper know whether Perl thinks something is a
number or a string?

Sorry for the long posting. As I said, someone must have hit this before
and I hope you can offer me some insight as I'm rather stuck with this
now.

Martin
-- 
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Reply via email to