csorrentini has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks,

I am working on an assignment that requires me to edit a module that will be called from another file. This module has subroutines to return the size in bytes of file, amount of lines in file, name of file, extension, last modified, type of file, contents of file and directory file is in.

While writing the subroutine to return the contents of the file (as an array) it just gives me a number for the output. Here is the subroutine code I made:

sub contents { open (FH, "< $FileInfoName") or die "Can't open $FileInfoName for re +ad: $!"; my @lines = <FH>; return @lines; close FH or die "Cannot close $FileInfoName: $!"; }
What am I missing to make this return the actual contents vs a number? Also this is the code that is calling it:
use strict; use TYPFileInfo; $FileInfoName = "FakeText.txt"; print "\nFilename: " . name(); print "\nExtension: " . extension(); print "\nModified: " . localtime( modified() ); print "\nBytes: " . bytes(); print "\nLines: " . lines(); print "\nType: " . type(); print "\nContents: " . contents();
Lastly, I am also trying to create a subroutine to return the directory the file is in. I have only found information on how to return contents of a directory but no how to actually return the directory itself. Thank you Monks!!

Replies are listed 'Best First'.
Re: Subroutines....return directory file is in and return contents in array
by toolic (Bishop) on Jun 26, 2014 at 19:24 UTC
    One thing Perlbotics did not explicitly mention is that the . is forcing scalar context. You can use comma to allow list context:
    print "\nContents: " , contents();
      Awesome thanks I'll try that now and look into those modules.
Re: Subroutines....return directory file is in and return contents in array
by Perlbotics (Archbishop) on Jun 26, 2014 at 19:20 UTC

    sub contents { open (FH, "< $FileInfoName") or die "Can't open $FileInfoName for re +ad: $!"; my @lines = <FH>; # return @lines; # 1st problem: in scalar context, number of lines is + returned # 2nd problem: next line is never reached close FH or die "Cannot close $FileInfoName: $!"; return join("", @lines); # fix: one big string with all lines concate +nated # See also File::Slurp }

    See module File::Basename to extract the directory name (dirname()) from the path, you already have. See module Cwd to get current working directory - if required.

    Update: oops - you wanted contents() to return an array (Perl: list) -- then you can keep the return @lines; (in last line) and change the callers context as toolic suggested.

    Maybe two other suggestions?

  • Avoid globals like $FileInfoName, use a parameter to contents() instead.
  • A more contemporary way is the three-arg-open plus avoiding globs like FH:
    e.g: open(my $file, '<', $FileInfoName) or die "..."; my @lines = <$file>; ...
    (and maybe chose a better name than $file (as I did here ;-) - something that is meaningful in the given context.
Re: Subroutines....return directory file is in and return contents in array
by poj (Abbot) on Jun 26, 2014 at 20:56 UTC
    You could have just one subroutine to return all the information
    #!perl use strict; use Cwd; use File::Basename; my $FileInfoName = $0; # this script my $hashref = info($FileInfoName); for my $key ( sort keys %$hashref){ print "$key : ".$hashref->{$key}." \n"; } sub info { my $filename = shift; my ($name,$path,$ext) = fileparse($filename,'\..*'); my @stat = stat($filename); my %info = ( 'Filename' => $name, 'Path' => $path, 'Ext' => $ext, 'Bytes' => $stat[7], 'Modified' => scalar localtime ($stat[9]), ); open FH,'<',$filename or die "$!"; my @lines = <FH>; close FH; $info{'Lines'} = scalar @lines; $info{'Contents'} = join '',@lines; return \%info; }
    poj