in reply to Re: Unsuccessful stat on file test
in thread Unsuccessful stat on file test

Thanks for the suggestion! I didn't even see the '\n' with my beginner's eyes! But now, my code reads like this:
#!/usr/bin/perl use warnings; use strict; sub filetest { my @answer; return "File does not exist\n"; unless -e $_; push @answer, "readable " if -r $_; push @answer, "writable " if -w $_; push @answer, "executable " if -x $_; return @answer; } while (<>) { s/\s*$//; my @answer = &filetest($_); print @answer; }


And now, no matter what file I feed the program, it reports "File does not exist". Also, if I remove the line
return "File does not exist\n"; unless -e $_;
the program executes quietly, not printing out any messages. I'm a little confused and befuddled by this.

Replies are listed 'Best First'.
Re^3: Unsuccessful stat on file test
by Corion (Patriarch) on Mar 02, 2008 at 20:07 UTC

    After fixing your typo:

    return "File does not exist\n"; unless -e $_;

    needs to become

    return "File does not exist\n" unless -e $_;

    the program works for me:

    C:\Projekte>perl -w tmp.pl tmp.pl readable writable

    So, maybe tell us more exactly what you're typing in, what files exist, and maybe consider adding some more debugging output to your file.

    Your form of calling the filetest function is bad/misleading. filetest is not using any parameters passed to it, it uses the global $_. So you should either call it as filetest(); or make your subroutine actually use its argument.

    As a style note, I never use the ampersand notation for function calls (&filetest()) - I find it too dangerous, because when I leave off the parentheses (&filetest;), that has the unintended side effect of calling filetest with the current values of @_ instead of passing no parameters at all.

Re^3: Unsuccessful stat on file test
by stiller (Friar) on Mar 02, 2008 at 20:16 UTC
    Your code is almost there, but you have to remove the semicolon:
    my @answer; return "File does not exist\n"; # <- extra semicolon! unless -e $_;

    The next problem is:

    while (<>) {
    If your program is named filetest.pl and you call it like:
    ./filetest.pl *.txt
    that loop is actually going to read each line of all the *.txt files in your current directory, and unless each line actually happens to be the name of a file in that directory, your program will correctly tell you that the file does not exists!

    Try adding some extra output (what is $_ ?)

    cheers

      By gum! With your help (and the help of the other posters)...I think I've got it! Hard work do pay off! Well, the prog isn't quite finished. There's still some debugging messages in there, and some tidying up to do.

      But basically it is now in a workable state. If I feed the program (which is named ex1-11, short for exercise 1 chapter 11) files with different modes, it will accuratley reflect those modes.

      Here's what I came up with:
      #!/usr/bin/perl use warnings; use strict; sub filetest { my @answer; print "\n\$_[0] now holds $_[0] \n"; return "File does not exist\n" unless -e $_[0]; push @answer, "readable " if -r $_[0]; push @answer, "writable " if -w $_[0]; push @answer, "executable " if -x $_[0]; print "function result: "; print @answer; return @answer; } while (@ARGV) { my $file = shift @ARGV; $file =~ s/\s*$//; print "\$file is $file"; my @answer = filetest($file); #thanks for the style tip! print "\nmain answer: "; print @answer; print "\n"; }
      Where I was falling down (mainly) was in the subroutine where I was confusing $_ with $_[0]. It was a few chapters ago, and sort of leaked out of my brain. There's a lot to retain to this Perl stuff! ;)

      Just wanted to dash off this note as a thanks to everyone who commented. I will try to finish up this program and begin the next one on the train into NYC tommorow.

      G'night, Monks!
Re^3: Unsuccessful stat on file test
by jwkrahn (Abbot) on Mar 02, 2008 at 21:00 UTC
    while (<>) {
        # some code
    }

    Is short for:

    while ( @ARGV ) {
        $ARGV = shift @ARGV;
        open ARGV;
        while ( defined( $_ = <ARGV> ) ) {
            # some code
        }
    }

    So you are reading from the files listed on the command line and using their contents as the file names to stat.    Perhaps you meant to do something like this instead:

    for ( @ARGV ) { my @answer = filetest( $_ ); print @answer; }