第12章 ディレクトリ操作 練習問題

Rubyに浮気したいなんていわないよ。*1

1. 指定されたディレクトリの内容をソートして表示

#!/usr/bin/env perl -w
use strict;

print "input directory name: ";
chomp(my $dir_name = <STDIN>);

if ($dir_name) { #入力があったら
    chdir $dir_name or die "cannot cd to $dir_name.\n";
} else {         #入力が無い時はホームディレクトリにchdir
    chdir or die "cannot cd to your home directory.\n";
}

#<>形式でglobする
foreach (sort <*>) {
    print "$_\n";
}

これで動くんですが、解答と照らし合わせると、もっとよくなります。<*>はsortしなくてももともとソートされているらしいので、ほんとはsortは必要ないですね。入力の判定は正規表現を使うとより良さそう。

2. 1のプログラムで.(ドット)ではじまるファイルも表示する

1の<>でglobするところを、

#<>形式でglobする
foreach (sort <.* *>) {
    print "$_\n";
}

とします。これはsortが必要。

3. 2をディレクトリハンドルを使って書き直す

1や2を参考に判定なんかを正規表現に変えています。

#!/usr/bin/env perl -w
use strict;

print "input directory name: ";
chomp(my $dir_name = <STDIN>);

if ($dir_name =~ m/^\s*$/){  #入力が空白の時は
    $dir_name = $ENV{'HOME'}; #ホームディレクトリを使う
}

#ディレクトリハンドルをopen
opendir DH, $dir_name or die "connot open $dir_name\n";

#ディレクトリハンドルを使う
my @files;
my $name;
push @files, $name while ($name = readdir DH);

print join "\n", sort @files; #ソートが必要
print "\n";

closedir DH;

解答を読んでみると、readdirをリストコンテキストで評価するのがここではスッキリするのがわかった。

# my @files;
# my $name;
# push @files, $name while ($name = readdir DH);
# よりもむしろ
my @files = sort readdir DH;

これで百倍すっきり。

*1:今はまだ