You think you're an X, but you're only a Y

The other day I was converting the output of a Git::Raw::Commit into JSON using my module JSON::Create, when I noticed an oddity:

{
"commits":[
    {
        "body":null,
        "id":"27ed4669e32ce2d14831c719dfd5b341a659788e",
        "message":"Remove a stray html ending tag\n",
        "time":"1609997818"
    },

The "time" part always comes out as a string, even though it's clearly a number. Was this a bug in my module, some kind of dual-string-and-number wannabee variable which JSON::Create falsely turned into a string?

As it happens, no. Git::Raw actually puts the number into a string. (The newSVpv there makes a new Perl string, and the sprintf above that does exactly the same job as Perl's sprintf.)

So Git::Raw turns the original C variable of the form git_time_t, a 64-bit integer type representing the number of seconds since the "epoch" (1970), into a string, perhaps to avoid the "year two million" problem or whatever, because Perl can hold up to 52 or 53 bit integers.

Anyway Perl's monkey business with numbers and strings, and the lack of booleans, makes creating JSON quite complicated, although not as complicated as identifying cats in photographs and youtube videos.

gary-7-cat-50pc.png

gary-7-cat-cat-50pc.png

4 Comments

I thought that as well when I had to deal with stricter consumers of my JSON but then, rooting through the Cpanel::JSON::XS docs and just reading into perl variables I just saw that for any number you can do latitude => $lat + 0 or have real booleans with
{
some_bool => $var ? \1 : \0,
}

But yes of course it's a bit of a pain if you dont have control over that..

Leave a comment

About Ben Bullock

user-pic Perl user since about 2006, I have also released some CPAN modules.