Previous | Table of Contents | Next |
Example: File Information ClassIf you recall from last hour, you built a module to give information on files. After building the module, it had a series of defects. Each of those defects can easily be fixed by using a class instead of a regular module. The object-oriented version of the file information module is presented in Listing 18.6. Listing 18.6. The FileInfo Module, as a Class.1: #!/usr/bin/perl -w 2: 3: package TYPFileInfoOO; 4: use strict; 5: 6: sub new { 7: my($class,$filename)=@_; 8: if (! -e $filename) { 9: die "$filename doesn't exist!"; 10: } 11: bless { filename => $filename }; 12: } 13: sub bytes { # Returns the size of the file in bytes 14: my($self)=@_; 15: return -s $self->{filename}; 16: } 17: sub lines { # Returns the number of text lines in the file 18: my($self)=@_; 19: my $count = 0; 20: open(FH, $self->{filename}) || die "Can't open $self->{filename}: $!"; 21: while(<FH>) { 22: $count++; 23: } 24: close(FH); 25: return $count; 26: } 27: sub name { # Returns just the filename portion of the path 28: my($self)=@_; 29: if ($self->{filename} =~ m/([\w\.]+)$/) { 30: return $1; 31: } 32: return $self->{filename}; 33: } 34: sub extension { # Returns just the extension portion of the filename 35: my($self)=@_; 36: if ($self->{filename} =~ m/\.(.*?)$/) { 37: return $1; 38: } 39: return ""; 40: } 41: sub modified { # Returns the last modified time, suitable for localtime() 42: my($self)=@_; 43: my @stats = stat($self->{filename}); 44: return $stats[9]; # Modified time. 45: } 46: 1; This listing is virtually unchanged from 17.8. The primary difference surrounds the fact that the global variable $FileInfoName is now gone.
The rest of the module continues the pattern of simply retrieving the filename from $self->{filename}. Remember that each instance of the class (each object) will have its own version of $self. Using the File Information ClassListing 18.7 shows how the class would be used to write the same program you wrote in Hour 17, "Writing Modules." Listing 18.7. A Reworking of Listing 17.9 with a Class1: #!/usr/bin/perl -w 2: 3: use strict; 4: use TYPFileInfoOO; 5: 6: my $fileInfo = new TYPFileInfoOO("/temp/message.txt"); 7: 8: print "\nFilename: " . $fileInfo->name(); 9: print "\nExtension: " . $fileInfo->extension(); 10: print "\nModified: " . localtime($fileInfo->modified()); 11: print "\nBytes: " . $fileInfo->bytes(); 12: print "\nLines: " . $fileInfo->lines();
Virtually no change, right? Well, like the Car class, the power of this class doesn't come out until you have multiple objects in play simultaneously. To demonstrate this, Listing 18.8 presents a program to sort a directory by file size. Listing 18.8. Using Multiple FileInfo Objects at Once1: #!/usr/bin/perl -w 2: 3: use TYPFileInfoOO; 4: 5: my @fileobjects; 6: foreach my $pathname ( glob("/temp/*.txt") ) { 7: if (-d $pathname) { 8: next; 9: } 10: push @fileobjects, new TYPFileInfoOO($pathname); 11: } 12: 13: foreach my $fileobj ( 14: sort { $a->bytes() <=> $b->bytes() } 15: @fileobjects ) { 16: 17: printf("%20s %9d %9d\n", 18: $fileobj->name(), $fileobj->bytes(), $fileobj->lines()); 19: }
The results (on my system) look something like this: chess.txt 135 8 sample.txt 456 30 outwords.txt 1031 141 message.txt 1112 36 parrot.txt 1152 144 outfile.txt 3799 1 NewSchedule.txt 4119 57 volleyball.txt 5289 440 log.txt 15529 363 This program would have been much more difficult to write using the old non-OOP version of the FileInfo module. Let's revisit the list of problems presented at the end of Hour 17, and see if we've solved any of them.
|
Previous | Table of Contents | Next |