Perl vs WindowsFS

xaicron (id:xaicron)

2009 11/20 Casual Perl Talks#1

10分のつもりで120枚ぐらいありますが

TAKESAKOメソッド(高橋メソッド?)では5分で100枚って書いてあったから大丈夫

自己紹介

自己紹介

  my $profile = {
    name => '嶋田 裕二',
    id   => 'xaicron',
    age  => 23,
  }

すぎゃーんさんをパクり参考にしました

自己紹介

Blog: にひりずむ::しんぷる
(http://blog.livedoor.jp/xaicron/)

id:xaicronの方はなんだかエロいことが書いてあるので大人になってから見ましょう(今は完全に放置ですが)

自己紹介

自己紹介

ちなみに

PHPは難しかったので挫折しました

当時はサーバー構築とかDB構築とかしないと動かないと思ってた

自己紹介

好きな言語は もちろんPerl

自己紹介

"I Perl"

さて

今日は、WindowsでPerlを今より少しだけ便利につかえるかもしれないモジュールを書いたのでご紹介します。

その名も

Win32::Unicode

予備知識

予備知識

Windowsのファイルシステムの文字コードについて

予備知識

Windowsでは1つのファイルに対して上記3種類のものが扱える

予備知識

Perlで通常扱えるのはcp932のみ

> ファイル名にUnicodeが含まれている場合は「?」になってしまう。

予備知識

こっちが「?」だよ!!!

予備知識

OSのバージョンによっては、8.3形式で帰ってくることも。

> 単純な読み書きは出来るが、Unicodeな名前にrenameとかは出来ない

予備知識

デモ1

予備知識

宮川さんのこの辺の記事もPerlとUnicode問題について詳しいです。

予備知識

どうすればいいの・・・?

> Windows捨ててLinuxとかMac使おうぜ!!

最近だとKindle

予備知識

でもWindowsじゃないとエロゲーが出来ないよ!!

> エロゲーもPerlもしたいよ!!

予備知識

なんとか扱えるように出来ないか?

> Win32::APIを使うといいっぽい!

Win32::APIとは

Win32::APIとは

use Win32::API;
my $MessageBox = Win32::API->new(
    "user32",      # 呼び出し元DLL名
    "MessageBoxA", # 呼び出す関数
    "NPPN",        # 関数の引数
    "N"            # 戻り値
);
$MessageBox->Call(0, "Hello, Casual!\n", "Message", 4096);

こんな感じで関数を呼び出してつかう

Win32::APIとは

使わない場合

use DynaLoader;
sub GetProcAddress {
    my ($DLL, $API) = @_;
    my $path = "$ENV{SystemRoot}\\system32\\$DLL";
    my $libref = DynaLoader::dl_load_file($path);
    pack "L", DynaLoader::dl_find_symbol($libref, $API);
}
my $x86 = ""
. "h\0\0\0\0"
. "h" . pack("P", "Message")
. "h" . pack("P", "Hello, World!\n")
. "h" . pack("L", 1024)
. "\xb8" . GetProcAddress("user32.dll", "MessageBoxA")
. "\xff\xd0" # call eax
. "\xc3"     # ret
;
DynaLoader::dl_install_xsub("X",unpack"L",pack"P",$x86);&X;

ちょっと難しい

Win32::APIとは

これを使えばUnicode文字が含まれてるファイルを扱える。

詳しくはhttp://subtech.g.hatena.ne.jp/miyagawa/20070815/1187134943

Win32::APIとは

が、しかし。

Win32::APIとは

というわけで

いろいろありましたが、

やっと本題

WindowsのUnicode関連のあれこれをすっきり解消したい!!

そんなあなたに

Win32::Unicode

Win32::Unicode

Win32::Unicode

Win32::Unicodeを使ったら

といったことはありませんが、便利です。

Win32::Unicodeの構成

Win32::Unicodeの構成

Win32::Unicodeの構成

単体で使う可能性があるものは以下の6つ

Win32::Unicode::Console

Win32::Unicode::Console

Win32::Unicode::Console

エクスポートされる関数

全部「W」がつく

Win32::Unicode::Console

use strict;
use warnings;
use utf8;
use Win32::Unicode::Console;

printW 'I ♥ Perl';

flagged utf8をそのままコマンドプロンプトに出力できる

Win32::Unicode::Console

デモ2

Win32::Unicode::Console

便利!!

Win32::Unicode::Console

Win32::Unicode::File

Win32::Unicode::File

Win32::Unicode::File

エクスポートされる関数

  • unlinkW
  • renameW
  • copyW
  • moveW
  • touchW
  • file_type
  • file_size

Win32::Unicode::File

IO::Fileっぽく

use strict;
use warnings;
use utf8;
use Win32::Unicode::File;

my $wfile = Win32::Unicode::File->new;
$wfile->open('>', '森鷗外.txt'); # Unicodeファイル
$wfile->binmode(':encoding(cp932)');
$wfile->write("こんにちわ Unicode\n");
$wfile->close;

Win32::Unicode::File

素のPerlっぽく

use strict;
use warnings;
use utf8;
use Win32::Unicode::File;

my $fh = Win32::Unicode::File->new;
open $fh, '>', "I \x{2665} Perl.txt"; # Unicodeファイル
binmode $fh, ':encoding(cp932)';
print {$fh} "こんにちわ Unicode\n";
close $fh;

Win32::Unicode::File

デモ3

Win32::Unicode::File

use utf8;
use Win32::Unicode::File;

my $file = "I \x{2665} Perl.txt";
if (file_type f => $file) {
    print file_size $file;
}

Win32::Unicode::File

Win32::Unicode::File

TODO

Win32::Unicode::Dir

Win32::Unicode::Dir

Win32::Unicode::Dir

エクスポートされる関数

  • mkdirW
  • rmdirW
  • getcwdW
  • chdirW
  • findW
  • finddepthW
  • mkpathW
  • rmtreeW
  • mvtreeW
  • cptreeW
  • dir_size
  • file_type
  • file_size

Win32::Unicode::Dir

use utf8;
use Win32::Unicode::Console;
use Win32::Unicode::Dir;

my $wdir = Win32::Unicode::Dir->new;
$wdir->open('森鷗外');
for my $file ($wdir->fetch) {
    sayW $file;
}
$wdir->close;

Win32::Unicode::Dir

デモ4

Win32::Unicode::Dir

File::Find

use utf8;
use File::Find;

find sub {
    my $file = $_;
    my $full_path = $File::Find::name;
    my $cwd = $File::Find::cwd;
    printf "%s : %s : %s\n", $file, $full_path, $cwd;
}, '.';

Win32::Unicode::Dir

File::Find Win32::Unicode::Dir版

use utf8;
use Win32::Unicode::Console;
use Win32::Unicode::Dir;

findW sub {
    my $file = $_;
    my $full_path = $Win32::Unicode::Dir::name;
    my $cwd = $Win32::Unicode::Dir::cwd;
    printfW "%s : %s : %s\n", $file, $full_path, $cwd;
}, '.';

Win32::Unicode::Dir

$Win32::Unicode::Dir::nameとか長すぎるので、第一引数で受け取れます。

Win32::Unicode::Dir

File::Find 第一引数版

use utf8;
use Win32::Unicode::Console;
use Win32::Unicode::Dir;

findW sub {
    my $perf = shift;
    printfW "%s : %s : %s\n", $perf->{file}, $perf->{path}, $perf->{cwd};
}, '.';

Win32::Unicode::Dir

超すっきりしましたね!!

Win32::Unicode::Dir

Win32::Unicode::Error

Win32::Unicode::Error

Win32::Unicode::Error

エクスポートされる関数

Win32::Unicode::Error

use utf8;
use Win32::Unicode::Console;
use Win32::Unicode::File;

my $fh = Win32::Unicode::File->new;
open $fh, '<', '存在しない.txt' or dieW errorW;
print join "\n", <$fh>;
close $fh;

Win32::Unicode

Win32::Unicode

さて

ここまで来て言うのもアレですが、

「W」はさすがに無くね?

www

「もうWなんて飽き飽きなんだよ!」

「おれはもっと普通にやりたいんだよ!!」

Win32::Unicode::(File|Dir)->newとかやってられないよ!!

そんなあなたに

Win32::Unicode::Native

Win32::Unicode::Native

Win32::Unicode::Native

エクスポートされる関数

いままでのから「W」を抜いたやつ

Win32::Unicode::Native

use utf8;
use Win32::Unicode::Native;

print "flagged utf8な文字も普通にいける";

# Win32::Unicode::File->newとかしない
open my $fh, '>', '森鷗外.txt' or die error;
print $fh "ほげほげ";
close $fh;

# Win32::Unicode::Dir->newとかしない
opendir my $dh, "\x{2600}" or die error;
say join "\n", readdir $dh;
close $dh;

Win32::Unicode::Native

完全にそのまま!!

Win32::Unicode::Native

ちなみに

use Win32::Unicode '-native'

でもOK

Win32::Unicode::Native

デモ5

Win32::Unicode::Native

だけど便利!!

かもしれない

そんなわけで

Perl vs WindowsFS

Perl WindowsFS

これからはもうUnicodeのファイルが来てもプッツンしない

健全な生活を歩むことができるようになりますね!!

Win32::Unicodeを使えば

WindowsでPerlを使うときはぜひ使って見てください!!

開発はgithubで行ってます (http://github.com/xaicron/p5-win32-unicode)

画像

CPANにあげる予定

そんなわけで

まとめ

初めて話をしたので至らない点も多かったと思いますが

最後まで聞いていただいてありがとうございました。

Casual Perlはゆる~いつながり

気軽に集まれるプログラマーの輪が広がっていくと、いろんなものがもっともっと生まれていくと思います。

これからもこういった集まりとかが出来るとすごくいいですね!!

今までトークしたことない自分も何か話せたし

普段は聴いているだけの人でも

ちょっとした勇気でスピーカーになれる!!

まぁ聴いているだけでもいいんですが。

結局何が言いたいかというと

Casual Perl++

開催してくださったyusukebeさん本当にありがとうございます!!

というわけで

ご清聴ありがとう
ございました。