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 を外して解決。

PostgreSQL 9.2beta2 と DBD::Pg

PostgreSQL 9.2beta2 を入れてみたら、DBIx::Class::Schema::Loader 付属の dbicdump でエラーになった。DBD::Pg の中でエラーになってる。

調べてみると PostgreSQL 9.2 で pg_tablespace.spclocation がなくなったのが原因と判明。→ http://archives.postgresql.org/pgadmin-hackers/2012-04/msg00044.php

ということで、DBD/Pg.pm を2行ほど書き換えたら動くようになりました。

% diff -c Pg.pm.orig Pg.pm
*** Pg.pm.orig  2012-07-09 14:43:14.810389674 +0900
--- Pg.pm       2012-07-09 14:52:12.815648538 +0900
***************
*** 727,733 ****
                  , quote_ident(n.nspname)
                  , quote_ident(c.relname)
                  , quote_ident(c2.relname)
!                 , i.indkey, quote_ident(t.spcname), quote_ident(t.spclocation)
                  , n.nspname, c.relname, c2.relname
              FROM
                  pg_catalog.pg_class c
--- 727,733 ----
                  , quote_ident(n.nspname)
                  , quote_ident(c.relname)
                  , quote_ident(c2.relname)
!                 , i.indkey, quote_ident(t.spcname), quote_ident(pg_tablespace_location(t.oid))
                  , n.nspname, c.relname, c2.relname
              FROM
                  pg_catalog.pg_class c
***************
*** 1151,1157 ****
                        # Default SQL
                        $extracols = q{,n.nspname AS pg_schema, c.relname AS pg_table};
                        my @search;
!                       my $showtablespace = ', quote_ident(t.spcname) AS "pg_tablespace_name", quote_ident(t.spclocation) AS "pg_tablespace_location"';

                        ## If the schema or table has an underscore or a %, use a LIKE comparison
                        if (defined $schema and length $schema) {
--- 1151,1157 ----
                        # Default SQL
                        $extracols = q{,n.nspname AS pg_schema, c.relname AS pg_table};
                        my @search;
!                       my $showtablespace = ', quote_ident(t.spcname) AS "pg_tablespace_name", quote_ident(pg_tablespace_location(t.oid)) AS "pg_tablespace_location"';

                        ## If the schema or table has an underscore or a %, use a LIKE comparison
                        if (defined $schema and length $schema) {

追記

DBD::Pg 2.19.3 で対応されましたね。

ZFSの拡張

ノートPCのVMWareで動かしているFreeBSDで、ディスク容量が不足気味になってきたんで、ZFSの拡張をしてみることにした。

念のためバックアップも取ったんだけど、以下の手順でわりとあっさり成功したなぁ。

  1. VMWare仮想マシン設定で「ハードディスク→ユーティリティ→拡張」を使って、ディスク容量を増やす。
  2. FreeBSD を起動して gpart コマンドで増えたことを確認。
  3. "gpart resize" でパーティションを拡張……しようとしたら、使用中なのでダメでした。ZFS root にしているので一時的に未使用にも出来ない。
  4. 仕方がないから boot-only の CD イメージを取ってきてそれで起動。シェルに入って gpart resize で無事パーティションサイズ拡張に成功。
  5. 普通に再起動する。
  6. "zpool online -e tank gptid/xxxxxx" でZFSの拡張完了。

Nethack クリア

プリン祭も飽きたので、さっさとイェンダー倒して最下層で法王倒して魔除けを手に入れて、一気に天上界へ。

精霊界では風の精が結構強かったな。強くなったとは知っていたけど、想像以上のもんでした。水晶玉で出口を確認して一目散だったけど、それでも450近くあるHPが3分の1くらいまで削られた。あって良かった超回復の呪文。

あとは、大量の敵が邪魔なんで争いの指輪を装備して被弾数を減らしたり、邪魔な敵を瞬間移動の杖で飛ばしたり、復活したイェンダーを死の指でぬっ殺したりしつつ天上界へ。祭壇は2回外れで最後が当たり。まずは右端まで行って、戻ってきて左の端までだったんで、さすがに命の魔除けが一つ砕けましたよ。5個くらい予備があるけどね。

てなわけで、魔除けを捧げてクリアです。

いかさま博覧亭

電撃コミック ジャパン」がwebからバックナンバーも含めて全部無料で読めるってのを今更ながらに聞きつけて、いかさま亭が面白かったので、怪異いかさま博覧亭の新装版も含めてまとめて購入。




いかさま博覧亭 1 (電撃ジャパンコミックス)

いかさま博覧亭 1 (電撃ジャパンコミックス)



絵に出てきている付喪神に、何匹かまだ名前がわからんのがいるなぁ。そのうちエピソード消化するんでしょうか?

オーフェン新装版6

魔術士オーフェンはぐれ旅 新装版 6

魔術士オーフェンはぐれ旅 新装版 6

今回も元は上下巻だったところですね。

(上)の方の後書きを読んだら「本編が薄っぺらい」って書いてあった。そういえば薄かったような気もするけど、上下合わせると他の新装版と大して厚みが変わらないから、(下)が結構長かったんだなと実感。