start page | rating of books | rating of authors | reviews | copyrights

Book HomeLearning Perl, 3rd EditionSearch this book

A.11. Answers to Chapter 12 Exercises

  1. Here's one way to do it, with a glob:

    print "Which directory? (Default is your home directory) ";
    chomp(my $dir = <STDIN>);
    if ($dir =~ /^\s*$/) {         # A blank line
      chdir or die "Can't chdir to your home directory: $!"; 
    } else {
      chdir $dir or die "Can't chdir to '$dir': $!";
    }
    
    my @files = <*>;
    foreach (@files) {
      print "$_\n";
    }

    First, we show a simple prompt, and read the desired directory, chomping it as needed. (Without a chomp, we'd be trying to head for a directory that ends in a newline -- legal in Unix, and therefore cannot be presumed to simply be extraneous by the chdir function.)

    Then, if the directory name is nonempty, we'll change to that directory, aborting on a failure. If empty, the home directory is selected instead.

    Finally, a glob on "star" pulls up all the names in the (new) working directory, automatically sorted to alphabetical order, and they're printed one at a time.

  2. Here's one way to do it:

    print "Which directory? (Default is your home directory) ";
    chomp(my $dir = <STDIN>);
    if ($dir =~ /^\s*$/) {         # A blank line
      chdir or die "Can't chdir to your home directory:
    $!"; 
    } else {
      chdir $dir or die "Can't chdir to '$dir': $!";
    }
    
    my @files = <.* *>;       ## now includes .*
    foreach (sort @files) {   ## now sorts
      print "$_\n";
    }

    Two differences from previous one: first, the glob now includes "dot star", which matches all the names that do begin with a dot. And second, we now must sort the resulting list, because some of the names that begin with a dot must be interleaved appropriately either before or after the list of things without a beginning dot.

  3. Here's one way to do it:

    print "Which directory? (Default is your home directory) ";
    chomp(my $dir = <STDIN>);
    if ($dir =~ /^\s*$/) {         # A blank line
      chdir or die "Can't chdir to your home directory:
    $!"; 
    } else {
      chdir $dir or die "Can't chdir to '$dir': $!";
    }
    
    opendir DOT, "." or die "Can't opendir dot: $!";
    foreach (sort readdir DOT) {
      # next if /^\./; ##   if we were skipping dot files
      print "$_\n";
    }

    Again, same structure as the previous two programs, but now we've chosen to open a directory handle. Once we've changed the working directory, we want to open the current directory, and we've shown that as the DOT directory handle.

    Why DOT? Well, if the user asks for an absolute directory name, like /etc, there's no problem opening it. But if the name is relative, like fred, let's see what would happen. First, we chdir to fred, and then we want to use opendir to open it. But that would open fred in the new directory, not fred in the original directory. The only name we can be sure will mean "the current directory" is ".", which always has that meaning (on Unix and similar systems, at least).

    The readdir function pulls up all the names of the directory, which are then sorted, and displayed. If we had done the first exercise this way, we would have skipped over the dot files, and that's handled by the uncommenting the commented-out line in the foreach loop.

    You may find yourself asking, "Why did we chdir first? You can use readdir and friends on any directory, not merely on the current directory." Primarily, we wanted to give the user the convenience of being able to get to their home directory with a single keystroke. But this could be the start of a general file-management utility program; maybe the next step would be to ask the user which of the files in this directory should be moved to offline tape storage, say.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.