2008-03-01から1ヶ月間の記事一覧

10.3 値を保持する局所変数を作成する

次の呼び出し時にも前の値をそのまま残してくれる変数を作成したい。ただし、この変数には、サブルーチンの外側からはアクセスできないようにしたい。 関数を別のブロックで囲み、my変数を関数のスコープ外、ブロックのスコープ内で宣言する。 { my $variabl…

10.2 関数内に局所変数を作成する

myを使用して、サブルーチン内でしか使用できない局所変数を宣言する。 sub somefunc { my $variable; # $variable変数にはsomefunc()関数の外部からはアクセスできない。 my ($another, @an_array, %a_hash); # 複数の変数を一度に宣言することも可能 }

10.1 サブルーチンの引数にアクセスする

直接アクセス sub hypotenuse { return sqrt( ($_[0] ** 2) + ($_[1] ** 2) ); } 名前付き局所変数にコピー sub hypotenuse { my ($side1, $side2) = @_; return sqrt( ($side1 ** 2) + ($side2 ** 2) ); }

10.17 多分岐文を書く

標準モジュールSwitchを使用する。 use Switch; switch ($value) { case 17 {print "number 17} case "snipe" {print "a snipe"} case /[a-f]+/i {print "pattern matched"} case [1..10,42] {print "in the list"} case (@array) { print "in the array"} c…

10.16 サブルーチンをネストする

一方のサブルーチンが、もう一方のサブルーチンからしか参照、呼び出しができないようにしたい。 内側の関数を通常のサブルーチンにするのではなく、クロージャにする。そして、そのリファレンスを適当な名前の型グロブに一時的に代入し、ローカル関数を作成…

10.15 AUTOLOADを使用して未定義の関数を捕捉する

未定義関数の呼び出しを捕捉したい。そしてそれらを適切に処理したい。 未定義関数と同じパッケージ内でAUTOLOADと言う名前の関数を定義する。未定義関数が呼び出された場合、このAUTOLOAD関数が代わりに呼び出され、その未定義関数の名前がパッケージ名付き…

10.14 関数を再定義する

関数の定義を一時的、もしくは恒常的に変更したい。しかし、既存の関数名に新しい関数の定義を関連づけることはできない。 関数を再定義するには、その関数と同じ名前の型グロブに新しく定義した関数のリファレンスを代入する。定義を一時的に変更したい場合…

10.13 グローバル変数の値を一時的に別の場所に保存する

local演算子を使用する。この値はブロックが終了した時点で、グローバル変数に自動的に戻される。 our $age = 18; if (CONDITION) { local $age = 23; func(); # 一時的な値23を参照 } # ブロックが終了したので、グローバル変数$ageには、元の値18が戻され…

10.12 例外を処理する

例外を発生させる可能性のある関数を安全に呼び出したい。また、例外を発生させる関数を作成したい。 例外を発生させる die "some message"; 例外を捕捉する eval { func() }; if ($@) { # $@に例外の内容が捕捉される。 warn "func raised an exception: $@…

10.10 エラーを返す

エラーが発生したことを表す値を関数から返す。 return文を引数を指定しないで書く。このようにすると、スカラーコンテキストでは、undefが返され、リストコンテキストでは、空のリスト()が返されます。 return;

10.11 関数のプロトタイプを宣言する

関数プロトタイプを使用して、コンパイラが引数の型をチェックできるようにしたい。 Perlの関数プロトタイプは、コンテキストを強制するもので、ユーザ定義の関数を組み込み関数(pushやpopなど)のように動作させたい場合に使用する。

10.9 複数の配列もしくはハッシュを戻り値として返す

配列もしくはハッシュのリファレンスを戻り値として返す ($array_ref, $hash_ref) = somefunc(); sub somefunc { my @array; my %hash; # ... return (\@array, \%hash); }

10.8 所要の戻り値のみ取得する

戻り値を代入するリスト内の不要な戻り値が返される位置にundefを格納する ($a, undef, $c) = func(); 戻り値のリストをスライスして、所要の戻り値のみを取得する ($a, $c) = (func())[0,2];

10.7 名前付きの引数を渡す

サブルーチン sub thefunc { my %args = ( INCREMENT => '10s', FINISH => 0, START => 0, @_, # 名前付きの引数のリストがここに格納される }; if ($args{INCREMENT} =~ /m$/ ) { ... } } 呼び出し側 thefunc(INCREMENT=>'20s', START=>'+5m', FINISH=>'+30…

10.6 戻り値のコンテキストを取得する

関数が呼び出されたコンテキストを取得したい。これができれば、コンテキストに応じた処理が行える。つまり、1つの関数で複数の処理が行える。 wantarray関数を使用する if (wantarray()) { # リストコンテキスト } elsif (defined wantarray()) { # スカラ…

9.11 8進数ではなく記号でパーミッションを操作する

Stat::IsModeを使用すると、数値形式のパーミッションを記号形式のパーミッションに変換できる。 use Stat::IsMode; $lsmode = file_mode($pathname); File::chmodを使用すると、記号形式のパーミッションを操作できる。 use File::chmod; chmod("g=rw, o=-w…

9.10 ファイル名を構成要素に分解する

フルパスから、ファイルの名前、ファイルを格納しているディレクトリの名前、拡張子を抽出したい。 FIle::Basenameモジュールを使用する use File::Basename; $base = basename($path); $dir = dirname($path); ($base, $dir, $ext) = fileparse($path);

9.9 ファイル名を変更する

foreach関数とrename関数を使用する。 foreach $file (@NAMES) { my $newname = $file; # $newnameを変更する処理を書く rename($file, $newname) or warn; }

9.8 ディレクトリとその中身を削除する

File::FIndモジュールのfinddepth関数を使用する。 例. rmtree1 #!/usr/bin/perl -w # rmtree1 - ディレクトリツリー全体を削除する(rm -rと同等) use File::Find; die "usage: $0 dir ..\n" unless @ARGV; find { bydepth => 1, no_chdir => 1, wanted => s…

9.7 ディレクトリ内の全てのファイルを再帰的に処理する

File::Findモジュールを使用する use File::Find; sub process_file { # 任意の処理を書く } find(\&process_file, @DIRLIST);

9.6 パターンにマッチするファイル名のリストを取得する

glob関数、もしくは<>演算子を使用する。 @list = <*.c>; @list = glob("*.c"); readdir関数を使用してファイル名を手動で抽出する opendir(DIR, $path); @files = grep { /\.c$/ } readdir(DIR); closedir(DIR);

9.5 ディレクトリ内の全てのファイルを処理する

opendir関数でディレクトリをオープンし、readdir関数で各ファイル名を取り出す。 opendir(DIR, $dirname) or die; while (defined($file = readdir(DIR)) { # "$dirname/$file"に対する処理を書く } closedir(DIR);

9.4 同じファイルに2つの名前が与えられていないか確認する

リスト内の2つのファイル名がディスク上の同じファイルに対応していないかどうか確認したい(ハードリンク、ソフトリンクにより、2つのファイル名が1つのファイルを参照している場合がある)。 ハッシュを作成し、キーとしてファイルのデバイス番号とiノード番…

9.3 ファイルをコピー、もしくは移動する

標準モジュールFile::Copyを使用する use File::Copy; copy($oldfile, $newfile); move($oldfile, $newfile);

9.2 ファイルを削除する

組み込み関数unlinkを使用する unlink($FILENAME) or die; unlink(@FILENAMES) == @FILENAMES or die;

9.1 タイムスタンプを取得、設定する

ファイルの最終更新時刻(書き込み、変更が行われた時刻)、最終アクセス時刻(読み込みが行われた時刻)を取得して変更したい。 stat関数で情報を取得し、utime関数で設定を行う。 ($READTIME, $WRITETIME) = (stat($filename))[8,9]; utime($NEWREADTIME, $NEW…

8.23 文字列をファイルとして扱う

文字列形式のデータをファイルとして扱いたい。例えば、引数としてファイルハンドルを受け取るサブルーチンに、直接文字列を渡して処理させたい。 open($fh, "+<", \$string); # $stringの中身の読み書きが可能

8.22 2つのファイルの内容を比較する

File::Compareモジュールを使用する use File::Compare; if (compare($FILENAME_1, $FILENAME_2) == 0) { # 2つのファイルが等しい場合 } if (compare(*FH1, *FH2) == 0) { # 2つのファイルが等しい場合 } if (compare($fh1, $fh2) == 0) { # 2つのファイル…

8.21 MicrosoftのテキストファイルをUnicodeに変換する

エンコーディングレイヤを適切に設定して、読み込んだテキストファイルをUnicodeに変換する。 binmode(IFH, ":encoding(cp1252)") || die;

8.20 ファイルハンドルに対して、Unicodeを読み書きする

入出力レイヤを使用して、特定のファイルハンドルからデータを読み込む場合、もしくは、特定のファイルハンドルにデータを書き込む場合には、特定のエンコーディングを使用するようにPerlに指示する。 open(my $ifh, "<:encoding(ENCODING_NAME)", $filename); open(my $ofh, ">:encoding(ENCODING_NAME)", $filename);</:encoding(encoding_name)",>