Perlの引数を内部コード化する

ファイル入出力や標準入出力は、binmodeでエンコーディングを設定しておけば、自動的に内部コードに変換されるが、環境変数コマンドライン引数は変換されない事があるため、別の処理で内部コード化する必要がある。
その処理をサブルーチンとして用意しておけば、変数毎に処理を書かずに済む。

use strict;
use warning;
use utf8;
use Encode;
use Encode::Guess qw(utf8 cp932 euc-jp);

binmode STDIN, ':encoding(cp932)';
binmode STDOUT, ':encoding(cp932)';
binmode STDERR, ':encoding(cp932)';

# 推測デコード
sub guess_decode($) {
    my $data = shift;
    
    my $guess_enc = guess_encoding($data);
    # 推測できる文字コードが複数ある場合、リファレンスではなく文字列が返される。
    unless(ref($guess_enc)) {
        # 文字列の場合、優先順位の高い順に"utf8 or cp932"のような形式になる。
        my @enc_list = split(m/(?:[\s]+)or(?:[\s]+)/o, $guess_enc);
        # 優先順位の高いほうのリファレンスを取得する。
        $guess_enc = find_encoding($enc_list[0]);
    }
    # デコードして、utf8フラグを付ける。
    $data = $guess_enc->decode($data);
    utf8::decode($data);
    
    return $data;
}

$prog_name = guess_decode($0);
$argA = guess_decode(ARGV[0]);
$argB = guess_decode(ARGV[1]);

print 'Program name : ' . $prog_name . "\n";
print 'Argument A : ' . $argA . "\n";
print 'Argument B : ' . $argB . "\n";