質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

Q&A

解決済

1回答

3123閲覧

Perl 再帰処理でファイル検索をするとカレントフォルダしか検索してくれない。

siusus

総合スコア25

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

再帰

情報工学における再帰とは、プログラムのあるメソッドの処理上で自身のメソッドが再び呼び出されている処理の事をいいます。

0グッド

0クリップ

投稿2017/03/02 16:20

WindowsでStrawberry_Perl5.24を使用しています。

再帰処理のことを勉強しています。"Higher-Order Perl"という書籍を参考にしてファイル検索スクリプトを書いたのですが、特定の条件分岐で下層のディレクトリを探してくれなくなってしまいました。

もちろん本の通りにコピペすれば問題なく動作するのですが、少しの書き方の違いでなぜここまで動作が異なるのか、理由がわかりません。

テスト用のフォルダやファイルを作ったりしてデバッカで動きを追ったりしたのですが、いまひとつ理解できませんでした。

ファイルテスト演算子"-d"を使った条件分岐 と単純なファイル名とディレクトリ記号との文字列比較による条件分岐は意味が異なるのでしょうか?

うまく動作しない理由が知りたいです。よろしくお願い致します。

###発生している問題・エラーメッセージ

0 : . 0 : ./R1 0 : ./R2 718 : ./recursive4.pl

###該当のソースコード

perl

1use strict; 2use warnings; 3 4use Data::Dumper; 5use utf8; 6use Encode; 7 8 9 10 11sub recursive { 12 my ( $base_dir, $func ) = @_; 13 my $DIR; 14 15 16 17 $func->($base_dir); 18 19 20 if (-d $base_dir){ 21 my $f; 22 if (!opendir $DIR, $base_dir) { warn "can't open directry"; return;} 23 24 while ($f = readdir $DIR){ 25 next if $f eq '.' || $f eq '..'; #正しく動作する条件分岐 26 next if ( -d $f ) ; #うまく動作してくれない条件分岐 27 28 recursive( "$base_dir/$f", $func); 29 30 31 } 32 } 33} 34 35 36 37my $code_ref = sub { 38 printf "%d \t:\t %s \n", -s $_[0], $_[0]; 39 40 }; 41 42recursive(".", $code_ref); 43

###補足情報(言語/FW/ツール等のバージョンなど)
本来のフォルダ構成は下記のようになっています。

0 : . 0 : ./AAA 0 : ./AAA/a1 0 : ./AAA/a2 0 : ./AAA/a3 0 : ./AAA/a4 0 : ./BBB 0 : ./BBB/b1 0 : ./BBB/b2 0 : ./BBB/b3 0 : ./R1 0 : ./R2 718 : ./recursive4.pl

これは本に書いてあったサンプルです。

perl

1sub print_dir { 2 printf "%6d %s\n",-s $_[0], $_[0] ; 3} 4 5 6 7 8sub dir_walk { 9 10 11my ($top, $code) = @_; 12my $DIR; 13 14$code->($top); 15 16if (-d $top) { 17 my $file; 18 unless (opendir $DIR, $top) { 19 warn "Couldn't open directory $top: $!; skipping.\n"; 20 return; 21 } 22 while ($file = readdir $DIR) { 23 next if $file eq '.' || $file eq '..'; 24 dir_walk("$top/$file", $code); 25 } 26 } 27}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Perl

1 while ($f = readdir $DIR){ # $DIR で表されるディレクトリ配下のディレクトリを列挙 2 next if $f eq '.' || $f eq '..'; # カレントディレクトリと親ディレクトリはスキップ 3 next if ( -d $f ) ; # その他のディレクトリもまとめてスキップ

結果何もしません。

投稿2017/03/02 17:04

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

siusus

2017/03/02 20:59

お世話になっております。 回答ありがとうございます。ものすごく根本的なことを聞いてしまったようで、なんだかすみません。 ファイルテスト演算子-dはカレントディレクトリ(.)と上位ディレクトリ(..)だけをチェックすると勝手に思い込んでいました。そうですよね。フォルダもディレクトリですよね・・・。 自分で「下層のディレクトリ」という単語を使っているのに、このことにまったく気付きませんでした。 本当に下手したら一生気付けなかったかもしれません・・・。本当に助かりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問