ファイル作成時,指定パスの存在を確認し,ディレクトリが存在しない場合に根元に近い既存ディレクトリからディレクトリを新規作成してパスを構築していくための処理。
● perl の場合
関数再帰呼び出しでパラメータのふるまいがおかしかったのでメモ。
こんな関数を作ったのだが……。
sub mkdirRc {
return( ( -d $_[0] )||
( $_[0] =~ /\/[^\/]+$/ && mkdirRc( $` ) &&
mkdir( $_[0], 0777 ) ) );
}
受け取ったパラメータのパスが既存なら真を返し(2行め),存在しなければ,最後のスラッシュより前の文字列,つまり親ディレクトリのパスを再帰的に自分に渡して再調査(3行め)をしてから,受け取ったパラメータ名でディレクトリを作る(4行め)。途中で何かエラーがあれば,ディレクトリは作られず偽を返す。
なかなかシンプルに書けたと思っていたが,正しく動作しない。途中で「File exists」というエラーが出る。つまり,存在しないディレクトリでも,「既に存在している(から作れない)」エラーが出る。
調べたところ,親ディレクトリを辿っていき,存在するディレクトリに行き着くと再帰呼び出しから返って来た時のパラメータ($_[0])が全てそのディレクトリ名になってしまうという現象が起きていた。だから,それ以降は既存ディレクトリ名で mkdir が呼び出されるらしい。
たとえば,このサブルーチンでファイルを作るためにパスを構築したい時は以下のように呼び出すわけだが……。
$filname = "/home/user/dir1/dir2/file"; $filname =~ /\/[^\/]+$/; mkdirRc( $` );
/home/user が既存の場合,親ディレクトリを辿ってそこに行き着くと,そこから返って来た時は呼び出した側の $_[0] も /home/user になってしまっていて,mkdir で「既に存在する」エラーが出てしまう。
こうしたら出なくなった。
sub mkdirRc { my $p = $_[0];
return( ( -d $p )||
( $p =~ /\/[^\/]+$/ && mkdirRc( $` ) &&
mkdir( $p, 0777 ) ) );
}
1行めの my $p に値を移しただけなのだが。パラメータ配列(@_)というのは,そのサブルーチン「唯一」のものなのか?
そのワリに,以下の「階乗」を求める関数は正常に動作する。
sub fact { return $_[0] ?( fact( $_[0]- 1 )* $_[0] ): 1; }
どういう現象なんだろ。


表計算で「令和」に対応する方法
表計算ソフトで予定表を自動作成する超便利な方法
«How to make the schedule table automatically on
spread-sheet.»
表計算ソフトに「個人情報保護機能」を仕込む方法
«Prevention to leak private-data with spread-sheet macro function.»
Wary-Basher (ワリバッシャー)
貧乏人を殺す行政の構造
«Structurally, the administrators kill the poors in Japan.»