「【Perl】Win32::GUI::LoftでGUIプログラミング」」ではThe GUI Loftを使ってGUIアプリケーションを書いた。
作成したアプリケーションを配布するときにはPAR::Packer
でexe化すると便利なのだが、スクリプトファイル(拡張子.pl
)の他にGUI定義ファイル(拡張子.gld
)もパッケージしないといけない。まずはパッケージ内部のgld
ファイルを読み込めるようにスクリプトを訂正しよう。
#!/usr/bin/perl use strict; use warnings; use FindBin; use Path::Class; use Win32::GUI::Loft; my $gld = "testGUI.gld"; my $scalar = $INC{ "PAR.pm" } ? PAR::read_file( $gld ) : file( $FindBin::Bin, $gld )->slurp; my $design = Win32::GUI::Loft::Design->newScalar( $scalar, $gld ); my $win = $design->buildWindow; $win->btnButton1->Change( -onClick => sub { -1 } ); $win->Show; Win32::GUI::Dialog;
ハイライトした部分が変更点だ。Perlの小ネタ集に書いたが、%INC
ハッシュの要素を調べることでPAR
モジュールを読み込んでいるかどうかがわかる。
これによってexe化したファイルから起動しているのかどうか判定しているわけだ。その上で、PAR::read_file
関数1を使ってファイルを読み込んでいる。
スクリプトを変更した上で、exe化を実行する。
C:\> pp -a testGUI.gld -o testGUI.exe testGUI.pl
-a
オプションによってパッケージにファイルを追加している。後は作成したtestGUI.exe
を配布するだけだ。
応用
YAMLで書いた設定ファイルをパッケージに追加する場合を考える。
開発中は同じディレクトリにある設定ファイル(config.yml
)を読み込み、配布するときにはパッケージに組み込んでしまう。このとき、設定ファイルを読み込んでハッシュリファレンスとして参照するコード例は次のようになる。
testYAML.pl
#!/usr/bin/perl use utf8; use strict; use warnings; use errors -with_using; use FindBin; use Path::Class; use Term::Getch; use YAML::Syck; binmode STDOUT => ":raw :encoding(cp932)"; binmode STDERR => ":raw :encoding(cp932)"; # ファイルのエンコードはCP932 # 改行コードは\x0D\x0Aとする my $config_file = "config.yml"; # try〜catch構文についてはこちら # https://blog.delphinus.dev/2010/01/use-errors.html my $option = try { # Unicodeを含んだファイルを読むときのおまじない local $YAML::Syck::ImplicitUnicode = 1; # 同じディレクトリにファイルがあった場合 my $file = file( $FindBin::Bin, $config_file ); if ( -f $file ) { my $fh = $file->openr; $fh->binmode( ":crlf :encoding(cp932)" ); LoadFile $fh; # exe化したパッケージ内にファイルがあった場合 } elsif ( $INC{ "PAR.pm" } ) { my $yaml = PAR::read_file( $config_file ); Load decode( cp932 => $yaml ); # それ以外はエラー } else { throw Error $config_file . "が見つかりません"; } } catch Error using { # $_には何らかのエラーメッセージが含まれている print <<EOM; 設定ファイルが読み込めません : $_ 何かキーを押してください EOM # 何かキーを押したら終了する # Term::Getchの使い方はこちら # https://blog.delphinus.dev/2010/03/perl-input-from-prompt.html my $char; 1 while ! ( $char = getch ); exit; }; # メインルーチン実行 &main( $option ); sub main { my $option = shift; print $option->{test} . "\n"; print $option->{test_ja} . "\n"; }
config.yml
--- test: Hello, World! test_ja: こんにちは、世界!
PAR::Packerでexe化
C:\> pp -a config.yml -o testYAML.exe testYAML.pl
実行例
C:\> testYAML Hello, World! こんにちは、世界!
-
これは
Archive::Zip::Member::contents
関数のラッパーである。 ↩