Perl

16.16 シグナルハンドラを一時的に上書きする

localを使用して、シグナルの動作を一時的にオーバーライドする # シグナルハンドラ sub ding { $SIG{INT} = \&ding; warn "\aEnter your name!\n"; } # 名前の要求をするために、SIGINTをオーバーライドする。 sub get_name { local $SIG{INT} = \&ding; my…

16.15 シグナルハンドラを設定する

%SIGハッシュを使用して、独自のハンドラをインストールする。 $SIG{QUIT} = \&got_sig_quit; # SIGQUITを受け取るたびに&got_sig_quitを呼び出す $SIG{PIPE} = 'got_sig_pipe'; # SIGPIPEを受け取るたびにmain::got_sig_pipeを呼び出す $SIG{INT} = sub {$o…

16.14 シグナルを送信する

killコマンドを使用する kill 9 => $pid; # $pidにシグナル9を送信する kill -1 => $pgrp; # ジョブ全体にシグナル1を送信する kill USR1 => $$; # 現在のプロセスにSIGUSR1を送信する kill HUP => @pids; # @pidsに含まれるプロセスにSIGHUPを送信する

16.13 利用可能なシグナルの一覧を表示する

% kill -l % perl -e 'print join(" ", keys %SIG), "\n";

16.12 異なるプロセス間で変数を共有する

forkによって分離したプロセスの間や関連性のないプロセスの間で変数を共有したい。 使用しているOSにおいて、SysV IPCがサポートされている場合には、それを使用する。

16.11 名前付きパイプを使用して、プロセスをファイルのように見せる

ファイルに対するアクセスを全てプログラムによって捕捉したい。例えば、自分の~/.planファイルをランダムな引用を返すプログラムにする。 名前付きパイプを使用する。 シェルで名前付きパイプを作成する。 % mkfifo /path/to/named.pipe 読み取り側のコード…

16.10 関連プロセスの間で通信する

関連性のある2つのプロセスがあり、これらの間で通信を行う必要がある。ただし、open, system, およびバッククォートによって行える以上に厳密な制御を行いたい。 pipeを使用してから、forkを使用する my ($reader, $writer); pipe $reader, $writer; if (fo…

16.9 別のプログラムの入力、出力、およびエラーを制御する

コマンドの入力、出力、およびエラーの各ストリームを完全に制御したい。 細心の注意を払いながら、標準モジュールのOPC::Open3を使用する。

16.8 別のプログラムの入力と出力を制御する

別のプログラムに対して、書き込みと読み取りを同時に行いたい。 標準モジュールのIPC::Open2を使用する use IPC::Open2; $pid = open2(*README, *WRITEME, $program); print WRITEME "here's your input\n; close(WRITEME); $output = <README>; close(README); wai</readme>…

16.7 プログラムのSTDERRを読み取る

コマンドのSTDOUTとSTDERRをまとめて変数に代入する。 $output = `cmd 2>&1`; # バッククォートの場合 # または、 $pid = open(PH, "cmd 2>&1 |"); # パイプ付きのopenの場合 while (<PH>) { } # さらに読み取りを行う コマンドのSTDOUTを変数に代入し、STDERRを</ph>…

16.6 入力を前処理する

gzipやcompressによって圧縮されたファイルをgzipによって圧縮解除して、自動的に処理する。 @ARGV = map { /\.(gz|Z)$/ ? "gzip -dc $_ |" : $_ } @ARGV; while (<>) { # ... } ファイルを処理する前にURLを取得する @ARGV = map { m#^\w+://# ? "GET $_|" …

16.5 出力をフィルタ処理する

自分のプログラムの出力を後処理する必要があるが、そのための独立したプログラムを作成したくない。 暗黙的にforkが行われる形式でopenを使用して、自分のプログラムにフィルタを接続する。 head(100); while (<>) { print; } sub head { my $lines = shift…

16.4 別のプログラムと読み書きする

別のプログラムを実行し、そのプログラムの出力の読み取りや、そのプログラムへの入力の書き込みを行いたい。 プログラムから出力を読み取る場合 $pid = open $readme, "-|", "program", "arguments" or die; while(<$readme>) { # ... } close $readme; プ…

16.3 現在のプログラムを別のプログラムに置き換える

実行中のプログラムを別のプログラムに置き換えたい。その際、別のプログラムを実行する前にパラメータを検査し、初期環境を設定する。 組み込みのexec関数を使用する。execを呼び出すときにメタキャラクタが含まれている引数を1個だけ渡すと、シェルが使用…

16.2 別のプログラムを実行する

1つのプログラムから別のプログラムを実行し、それが終了した後で、元のプログラムの実行を継続したい。その際、別のプログラムでも元のプログラムと同じSTDIN, STDOUTを使用する。 引数として1個の文字列を渡してsystemを呼び出し、その文字列がシェルによ…

16.1 プログラムから出力を収集する

プログラムを実行したときに、その出力を収集して、変数に保存したい。 バッククォートを使用する $output = `program args`; # 1個の複数行文字列に出力を収集する @output = `program args`; # 各要素に1行ずつ割り当てた配列に出力を収集する パイプを使…

15.20 イメージにテキストを追加する

CPANのGDモジュールを使用する use GD; $image = GD::Image->new($FILENAME); $blue = $image->colorAllocate(0,0,255); $image->string(gdTinyFont, 10, 10, "Copyright Me, 2037", $blue); # $image->png()でファイルに書き込む

15.19 イメージの縮小版を作る

CPANのImage::Magickモジュールを使用する use Image::Matick; $image = Image::Magick->new(); $image->Read($ORIGINAL_FILENAME); $image->Resize(geometry => '120x90'); $image->Write($THUNBNAIL_FILENAME);

15.18 データをグラフ化する

数値データがあるので、それを棒グラフ、円グラフ、折れ線グラフなどで表したい。 CPANのGD::Graph::*モジュールを使用する use GD::Graph::lines; # bars, lines, points, pie $chart = GD::Graph::lines->new(480, 320); $chart->set( x_label => $X_AXIS_…

15.17 Windows Perl/TkでDOSシェルウィンドウを消去する

プログラムの最初の部分に、次のコードを追加する BEGIN { if ($^O eq 'MSWin32') { require Win32:Console; Win32::Console::Free(); } }

15.16 Tkのサイズ変更イベントに応答する

Confiureイベントを捕捉することによって、ユーザがウィンドウのサイズを変更するのを防ぐ use Tk; $main = MainWindow->new(); $main->bind('<Configure>' => Sub { $xe = $main->XEvent; $main->maxsize($xe->w, $xe->h); $main->minsize($xe->w, $xe->h); });</configure>

15.15 Tkでダイアログボックスを作成する

Tk::DialogBoxウィジェットを使用する use Tk::DialogBox; $dialog = $main->DialogBox ( -title => "Register This Program", -buttons => [ "Register" , "Cancel" ] ); # $dialog->Add()を使用して、ダイアログボックスにウィジェットを追加する # 後でダ…

15.14 Tkでメニューを表示する

TkのMenubuttonおよびFrameウィジェットを使用する。 use Tk; $main = MainWindow->new(); # メニューを表示するための水平方向の領域をウィンドウの最上部に作成する $menubar = $main ->Frame(-relief => "raised", -borderwidth => 2) ->pack(-anchor => …

15.13 Expectで他のプログラムを制御する

STDINとSTDOUTに端末を通じてアクセスすることが前提になっているフルスクリーンプログラムの対話型操作を自動化したい。 CPANのExpectモジュールを使用する。 use Expect; $command = Expect->spawn("program to run") or die; # プログラムの出力がSTDOUT…

15.12 画面を制御する

画面のレイアウトや強調表示の制御、特殊キーが押された場合の検出、フルスクリーンメニューの表示などを行いたい。ただし、ユーザがどのような種類のディスプレイデバイスを使用しているかについては配慮する必要を無くしたい。 CPANのCursesモジュールを使…

15.11 入力を編集する

ユーザが入力行を送信してプログラムに読み取らせる前に、その入力行をユーザ自身が編集できるようにしたい。 Term::ReadLineモジュールを使用する。 use Term::ReadLine; $term = Term::ReadLine->new("APP DESCRIPTION"); $OUT = $term->OUT || *STDOUT; $…

15.10 パスワードを読み取る

キーボードからの入力を読み取るときに、そのキーの入力が画面にエコーされないようにする。 CPANのTerm::ReadKeyモジュールを使用して、その入力モードをnoechoに設定した後で、ReadLineを使用する use Term::ReadKey; ReadMode('noecho'); $password = Rea…

15.9 待機状態の入力を検査する

キーボードからの入力が実際に読み取られずに待機状態になっているかどうかを検査したい。 CPANのTerm::ReadKeyモジュールを使用して、引数として-1を渡すことによって、非ブロックモードによるキーの読み取りを試みる。 use Term::ReadKey; ReadMode ('cbre…

15.8 POSIX termiosを使用する

端末の特性を直接設定したい POSIXモジュールのtermiosインターフェースを使用する

15.7 端末のビープ音を制御する

"\a"文字を出力する print "\aWake Up!\n"; "vb"端末機能を使用して、ビジュアルレベルを表示する use Term::Cap; $OSPEED = 9600; eval { require POSIX; my $termios = POSIX::Termios->new(); $termios->getatt; $OSPEED = $termios->getospeed; }; $term…