Path::Class::Dir - ディレクトリのオブジェクト表現
use Path::Class qw(dir); # 短いコンストラクタのエクスポート my $dir = dir('foo', 'bar'); # Path::Class::Dirオブジェクト my $dir = Path::Class::Dir->new('foo', 'bar'); # 同様 # Unixでは'foo/bar'、Windowsでは'foo\bar'などに文字列化 print "dir: $dir\n"; if ($dir->is_absolute) { ... } my $v = $file->volume; # Windowsでは'C:'、Unixではから文字列、 # Mac OSでは'Macintosh HD:'など $file->cleanup; # パスネームの論理的なクリーンナップ my $file = $dir->file('file.txt'); # このディレクトリ内のファイル my $subdir = $dir->subdir('george'); # サブディレクトリ my $parent = $dir->parent; # 親ディレクトリ'foo' my $abs = $dir->absolute; # 絶対パスへの変換 my $rel = $abs->relative; # 相対パスへの変換 my $rel = $abs->relative('/foo'); # /fooへの相対パス print $dir->as_foreign('MacOS'); # :foo:bar: print $dir->as_foreign('Win32'); # foo\bar
# IO::Dirメソッドによるイテレート: my $handle = $dir->open; while (my $file = $handle->read) { $file = $dir->file($file); # Turn into Path::Class::File object ... } # Path::Classメソッドによるイテレート: while (my $file = $dir->next) { # $fileはPath::Class::FileまたはPath::Class::Dirオブジェクト ... }
Path::Class::Fileクラスはクロス・プラットフォームな方法でのディレクトリ名の操作のための機能を含みます。
Path::Class::Dirオブジェクトを生成し、これを返します。
この引数では、連結されて単一のディレクトリオブジェクトを生成するのに使われるディレクトリ名を指定します。
何らかのボリュームを最初の引数で、あるいは最初の引数の一部分で指定することができます。
プラットフォーム-ニュートラルな記述:
my $dir = dir( 'foo', 'bar', 'baz' );
あるいは、プラットフォーム-ネイティブな記述:
my $dir = dir( 'foo/bar/baz' );
あるいは、この二つの混合ができます:
my $dir = dir( 'foo/bar', 'baz' );
上の三つの例はいずれも、相対パスを生成します。 絶対パスを生成するには、プラットフォーム-ネイティブな次のような記述:
my $dir = dir( '/var/tmp' );
または最初の引数としてから文字列を記述します:
my $dir = dir( '', 'var', 'tmp' );
二番目の形式は不恰好に見えるとすれば、それは意図的なことです - 最初に挙げた/var/tmpあるいは\Windowsのようなパスはクロスプラットフォームのコンセプトではなく、もしあなたがコードをクロスプラットフォームにしようとしているなら、おそらくその中に現れるべきではありません。
これが設定ファイル、ユーザ入力、その他から与えられるのであれば、最初の形態はあらゆる意味ですばらしいものです。
特別なケースとして、有用でありこの方法で定義できると便利だからという以外の意味はありませんが、Path::Class::Dir->new()(あるいはdir())は現在のディレクトリ(File::Spec->curdir)を指します。現在のディレクトリを絶対パスで得るには、dir()->absoluteとします。
このメソッドはPath::Class::Dirが文字列コンテクストで使われたときに自動的に呼ばれるもので、したがって以下は同じことになります:
$string = $dir->stringify; $string = "$dir";
このディレクトリオブジェクトにボリューム(例えば、WindowsではC:、Mac OSではMacintosh HD:など)があれば、それを返します。
そうでなければ、空文字列を返します。
このオブジェクトがディレクトリをあらわしているか、boolean(真偽)値で返します。
当然のことですが、Path::Class::Fileは常にfalseを返しますし、Path::Class::Dirは常にtrueを返します。
ディレクトリが絶対パス指定(/usr/localや\Windowsのように)を指しているか否かに応じて、trueかfalseを返します。
ファイルパスの論理的なクリーンナップを行います。例えば:
my $dir = dir('/foo//baz/./foo')->cleanup; # $dirは'/foo/baz/foo'をあらわします;
$dirまたはこのサブディレクトリの一つの中のものをあらわすPath::Class::Fileオブジェクトを返します。
内部的には、Path::Class::File->new( @_ )を呼ぶだけです。
$dirのサブディレクトリをあらわす新しいPath::Class::Dirオブジェクトを返します。
$dirの親ディレクトリを返します。
これは論理的な親であり、必ずしも物理的な親であるとは限らないことに注意指定下さい。
実際に意味するのは、これいじょう切り落とせなくなるまで、ディレクトリリストの末端からエントリを切り落とすというだけです。
もしディレクトリが相対であれば、親ディレクトリの相対での形式を使用するところから始めます。
以下のコードは絶対及び相対ディレクトリの振る舞いのデモンストレーションです:
$dir = dir('/foo/bar'); for (1..6) { print "Absolute: $dir\n"; $dir = $dir->parent; } $dir = dir('foo/bar'); for (1..6) { print "Relative: $dir\n"; $dir = $dir->parent; } ########### Output on Unix ################ Absolute: /foo/bar Absolute: /foo Absolute: / Absolute: / Absolute: / Absolute: / Relative: foo/bar Relative: foo Relative: . Relative: .. Relative: ../.. Relative: ../../..
このディレクトリ内のオブジェクトをリストアップし、Path::Class::FileおよびPath::Class::Dirのリスト、またはスカラコンテキストではその数として返します。
分かりきったことですが、子を検索するためには$dirが存在し、読み込み可能であることが必要です。
子は$dirのサブディレクトリとして、つまりfooの子はbarやbazではなく、foo/barやfoo/bazとして返されることに注意してください。
基本的に、children()はselfとparentにあたるエントリーの.や..(あるいは非Unixシステムのこれにあたるもの)を含みません。
これはI'm-my-own-grandpaビジネスのようなものですから。
これらの特別なものを含むディレクトリ・エントリが欲しいのであれば、allにtrueの値を渡してください:
@c = $dir->children(); # 子のみ @c = $dir->children(all => 1); # 全てのエントリ
$dirを絶対パスであらわしたPath::Class::Dirオブジェクトを返します。
追加引数として、文字列かPath::Class::Dirオブジェクトで、相対パスのベースとして使われるディレクトリを指定することができます。
指定しなかった時は、現在のワーキング・ディレクトリが使われます。
$dirを相対パスであらわしたPath::Class::Dirオブジェクトを返します。
追加引数として、文字列かPath::Class::Dirオブジェクトで、相対パスのベースとして使われるディレクトリを指定することができます。
指定しなかった時は、現在のワーキング・ディレクトリが使われます。
subsumes($other)
ディレクトリ指定が、他方のディレクトリ指定に含まれているものであればtrueを、そうでなければfalseを返します。
``subsumes''は``contains''だと考えることもできますが、$dirが実際にファイルシステム上で$otherを含んでいるかではなく、指定だけを見ています。
$other引数はPath::Class::Dirオブジェクト、Path::Class::Fileオブジェクト、文字列のどれでもかまいません。
最後のケースでは、これをディレクトリであると仮定します。
# 例:
dir('foo/bar' )->subsumes(dir('foo/bar/baz')) # True
dir('/foo/bar')->subsumes(dir('/foo/bar/baz')) # True
dir('foo/bar' )->subsumes(dir('bar/baz')) # False
dir('/foo/bar')->subsumes(dir('foo/bar')) # False
as_foreign($type)
$dirを$typeタイプのシステムで指定した場合のPath::Class::Dirオブジェクトを返します。
既知のタイプにはUnix、Win32、Mac、VMS、そしてOS2、つまりFile::Specにサブクラスがあるすべてのものが含まれます。
生成されたオブジェクト(サブディレクトリ、ファイル、親ディレクトリなど)はこのタイプを保持します。
$dirを$typeタイプのシステムで指定した場合のPath::Class::Dirオブジェクトを返します。
既知のタイプにはUnix、Win32、Mac、VMS、そしてOS2、つまりFile::Specにサブクラスがあるすべてのものが含まれます。
@argsに含まれる引数は、new()で指定されるものと同じです。
このディレクトリ構成を内部的に示す文字列のリストを返します。
リストのそれぞれの連続したメンバーは、その前のもののディレクトリリストのエントリーだと理解されます。
約束として、Path::Class->new( $dir->dir_list )は$dirと等価です。
このメソッドの意味合いはPerlのspliceまたはsubstr関数に類似しています;OFFSETから初めてLENGTH個の要素を返します。
LENGTHが省略されると、OFFSETからリストの最後までのすべての要素を返します。
LENGTHがマイナスであれば、OFFSETより前方の末尾-LENGTH個の要素を返します。
OFFSETがマイナスであれば、リストの末尾からOFFSET個の要素を数えます。
OFFSETとLENGTHが両方とも省略されると、全体のリストを返します。
スカラコンテキストでは、引数なしのdir_list()はディレクトリリストのエントリの個数を返します;
dir_list(OFFSET)は個のオフセット位置の要素一つを返します;
dir_list(OFFSET, LENGTH)はリストコンテキストで返された要素の最後のものを返します。
open()
$dirを含む与えられた引数すべてをIO::Dir->newに渡し、その結果をIO::Dirオブジェクトとして返します。
openが失敗すると、undefが返され$!がセットされます。
$dirを含む与えられた引数すべてをFile::Path::mkpath()に渡し、結果(作成されたすべてのディレクトリ)を返します。
$dirを含む与えられた引数すべてをFile::Path::rmtree()に渡し、結果(削除に成功したファイル数)を返します。
remove()
ディレクトリを削除しますが、空であることが必要です。
ディレクトリの削除に成功したか否かを示すboolean(真偽)値を返します。
このメソッドは主に、Path::Class::Fileのremove()メソッドとの一貫性のために提供されます。
next()
ディレクトリのコンテンツ一通りにイテレート(反復)を行うのに便利な方法です。
最初にnext()が呼ばれると、ディレクトリをopen()し、ここから最初のアイテムを読み込み、結果をPath::Class::DirまたはPath::Class::File(もちろん、実際のタイプがどちらかによります)で返します。
以降のnext()呼び出しは、ディレクトリ内のコンテンツに対して単に反復され、ディレクトリ内にそれ以上のアイテムがなくなると、未定義値が返されます。
ディレクトリ内の通常ファイルすべてに対してイテレートをする例です:
while (my $file = $dir->next) { next unless -f $file; my $fh = $file->open('r') or die "Can't read $file: $!"; ... }
ディレクトリを開く際にエラー(例えば存在しないか読み取り不可)が発生すると、next()は$!の値とともに例外を投げます。
このディレクトリと、全ての子、全ての子の子、etc.に対して反復して、それぞれのエントリに対するcallbackサブルーチンの呼び出しを行います。
これは多くの点でFile::Findモジュールが行うことに似ており、もちろんFile::FindはPath::Classオブジェクト上でもよく動作しますが、recurse()メソッドにはコールバック・サブルーチンに単なるパス名の文字列ではなくPath::Classオブジェクトを送るという利点があります。
recurse()メソッドは各エントリに対して呼び出されるサブルーチンがcallbackパラメータで指定されることを要求します。
これはPath::Classオブジェクトを第一引数として渡されます。
recurse()はさらに二つの再起処理順をコントロールするbooleanパラメータ、depthfirstとpreorderを受け取ることができます。
デフォルトはpreorderで、横型探索、つまりdepthfirst => 0, preorder => 1です。
これを書いている時点では、depthfirst => 0, preorder => 0を除く全ての両パラメータの組み合わせがサポートされています。
stat()
このディレクトリでFile::stat::stat()を呼び出し、その結果を示すFile::statオブジェクトを返します。
lstat()
stat()と同じですが、$fileがシンボリックリンクの時は、lstat()はリンクの指すファイルの代わりにリンクのstatを行います。
Ken Williams, ken@mathforum.org
Path::Class, Path::Class::File, File::Spec
Makio Tsukamoto, tsukamoto@gmail.com