Data::Dumper の日本語文字化けと Syntax::Collector。


古いメモより。

`Data::Dumper` のメモと、`Syntax::Collector` のメモくっつけたら、 後者の方が長かった、、、

## Data::Dumper の日本語文字列の扱いを変更させる。

`use Data::Dumper` したら文字化けする、っての対応。

```
{
    package Bar ;
    use Data::Dumper ;
    no warnings 'redefine' ;
    *Data::Dumper::qquote = sub { return shift } ;
    $Data::Dumper::Useperl = 1 ;
}

use Data::Dumper ;
use utf8  ;
my $v = '日本語文字列' ;
print Dumper \$v ;
```

まあ、別に、パッケージを分ける必要もないけれど。

- `qquote` を再定義して、処理させない。
- `$Data::Dumper::Useperl = 1` して、XS 使わない。

「Dump する文字列は、全て UTF-8 フラグ付いてますよ。」って自信がある人は、

```
use Encode ;
*Data::Dumper::qquote = sub { return encode "utf8", shift ;} ;
```

とすると、

`Wide character in print at ` なエラーは避けられます。

## Syntax::Collector

これらのコードをいちいち書くのが面倒な人への一例として。


### install

`plenv` でローカルにインストールしてる環境で。

```
$ cpanm Syntax::Collector
```

### Syntax.pm

```
package Syntax ;
use Data::Dumper ;
use Encode ;
no warnings 'redefine' ;
*Data::Dumper::qquote = sub { return encode "utf8", shift ;} ;
$Data::Dumper::Useperl = 1;

use Syntax::Collector <<EOF;
    # core modules
    use strict 0 ; 
    use warnings 0;
    use autodie  0;
    use Data::Dumper 0 ;
    use utf8 0 ;
EOF

1;
```

### 実行コード

`Syntax.pm` と同じディレクトリにて。


```
use Syntax ;
my $v = '日本語文字列' ;
print Dumper $v  ;
print $v . "\n" ;
```

とでもして確認してみる。


## グローバルな特殊変数とか。

上の例で分る通り、グローバルな特殊変数とか、グローバルなモジュール由来の変数とかに関しては、Syntax.pm の中で設定してしまうのが吉。
以下に二つ程、追加の例を

### `setlocale`

まあ、（シェルの方の） `$LANG` 変えちゃうのが楽だとは思うんだけど、簡単な例として。

```
package Syntax ;
use POSIX qw( setlocale LC_ALL ) ; 
setlocale( LC_ALL, 'C' ) ;
use Syntax::Collector <<EOF;
    use POSIX 0 qw( strftime ) ;
EOF

1;
```

```
$ perl -le 'print strftime( "%A, %B %d, %Y", localtime );' -MPOSIX=strftime
木曜日, 11月 05, 2015
$ perl -le 'print strftime( "%A, %B %d, %Y", localtime );' -MSyntax
Thursday, November 05, 2015
```

### `@INC`

ちょっと複雑な例として。
実行スクリプト `CODE.pl` との関係で、

```
/PATH/TO
+--/APP
   +--CODE.pl
   +--/lib
      +--A.pm
      +--Sytax.pm
+--/lib
   +--B.pm
```

こんな関係を常に保っていて、/PATH/TO も流動する場合[^1]に、`A.pm`, `B.pm` を、きちんと use する。
[^1]: NFS マウントして、マウントポントは別名。双方それぞれ利用するとか。

#### Sytax.pm
```pl:/PATH/TO/APP/lib/Sytax.pm
package Syntax ;
use Cwd 'realpath' ;
use File::Basename ;
BEGIN{ shift @INC } ;
use lib (
    +( dirname realpath __FILE__ ) ,
    +( realpath +( dirname realpath __FILE__ ) . q{/../../lib} )
) ;

use Syntax::Collector <<EOF;
    use Data::Dumper 0 ;
    use A 0 ;
	use B 0 ;
EOF

1;
```

#### A.pm/B.pm

```pl:/PATH/TO/APP/lib/A.pm
package A ;
print "A\n" ;
1;
```

```pl:/PATH/TO/lib/B.pm
package B;
print "B\n" ;
1;
```

#### CODE.pl

```pl:/PATH/TO/APP/CODE.pl
use File::Basename ;
use lib +( dirname __FILE__ ) . q{/lib} ;
use Syntax ;

print Dumper \@INC
```

適当な場所で実行

```
$ perl /PATH/TO/APP/CODE.pl
A
B
$VAR1 = [
          '/PATH/TO/APP/lib',
          '/PATH/TO/lib',
          '${PLENV_ROOT}/versions/5.18.4/lib/perl5/site_perl/5.18.4/darwin-2level',
          '${PLENV_ROOT}/versions/5.18.4/lib/perl5/site_perl/5.18.4',
          '${PLENV_ROOT}/versions/5.18.4/lib/perl5/5.18.4/darwin-2level',
          '${PLENV_ROOT}/versions/5.18.4/lib/perl5/5.18.4',
          '.'
        ];
```


- `@INC` はグローバル 
	- `@INC` の、 `.` は、最初から存在を無視する事。
	- `use lib` で `@INC` の最初に追加されるので、 CODE.pl 側からの登録分は一応 shift で削る。
	- `@INC` 登録分が、全て絶対パスなので、あとは `use` し放題。
- `__FILE__` は現在のファイルの事。