Answers to Chapter 12 Exercises
Here’s one way to do it:
foreach my $file (@ARGV) { my $attribs = &attributes($file); print "'$file' $attribs.\n"; } sub attributes { # report the attributes of a given file my $file = shift @_; return "does not exist" unless -e $file; my @attrib; push @attrib, "readable" if -r $file; push @attrib, "writable" if -w $file; push @attrib, "executable" if -x $file; return "exists" unless @attrib; 'is ' . join " and ", @attrib; # return value }In this one, once again it’s convenient to use a subroutine. The main loop prints one line of attributes for each file, perhaps telling us that
'cereal-killer'is executable or that'sasquatch'does not exist.The subroutine tells us the attributes of the given filename. Of course, if the file doesn’t even exist, there’s no need for the other tests, so we test for that first. If there’s no file, we’ll return early.
If the file does exist, we’ll build a list of attributes. (Give yourself extra credit points if you used the special
_filehandle instead of$fileon these tests, to keep from calling the system separately for each new attribute.) It would be easy to add additional tests like the three we show here. But what happens if none of the attributes is true? Well, if we can’t say anything else, at least we can say that the file exists, so we do. Theunlessclause uses the fact that@attribwill be true (in a Boolean context, which is a special case of a scalar context) if it’s got any elements.But if we’ve got some ...