Perl で Data::Dumper を使うと JSON 出力で小数点付き数値が文字列として出力される

PerlJSON 型式のデータを出力するプログラムを書いていた時のこと。

JSONで出力したときに数値が文字列扱いされてしまうのでしばらく苦労したんだけど、原因が判明。

どうやら、デバグ用に Data::Dumper を入れていたのが原因らしく、一度 Dumper にかけると、JSON で出力するときに小数点付きの数値が文字列扱いになってしまうらしい。

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use JSON;

my $data = {
    a => 1,
    b => 2.2,
    c => -3,
    d => 1.2E3,
    e => {
        x => 4,
        y => 5.5,
    },
};

print "Before\n";
print JSON->new->encode($data), "\n\n";

print "Dump\n";
print Dumper($data), "\n\n";

print "After\n";
print JSON->new->encode($data), "\n";

これを実行すると、

% perl test.pl
Before
{"e":{"y":5.5,"x":4},"c":-3,"a":1,"b":2.2,"d":1200}

Dump
$VAR1 = {
          'e' => {
                   'y' => '5.5',
                   'x' => 4
                 },
          'c' => -3,
          'a' => 1,
          'b' => '2.2',
          'd' => '1200'
        };


After
{"e":{"y":"5.5","x":4},"c":-3,"a":1,"b":"2.2","d":"1200"}

こんな具合。

よく見ると Dumper の出力時点で、すでに文字列扱いですな。指数表記も Dumper の時点で文字列になってる。

Perl だと数値として見える文字列と、数値は普段は区別しなくていいけど、たまにこういう影響が出ることがあるんだなぁ。

ということで、とりあえず Data::Dumper を外して解決。