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

Hi all, I'm new to Perl so therefore I'm struggling a bit in some areas... I would like to encapsulate the follwoing if check in a function with call parameters
if(-e,-w "c:\\myfile.txt") { print"File exists"; }
Here now the function with function call and the two parameters the operator -e,-w and the filename. Basically this should work, but somehow when i try to compare this two arguments the interpreter reports a error. I tried to use eval to evaluate the variable $_[0] firs befor I using this in the if condition. Any ideas?
checkit("-e,-w", "c:\\myfile.txt"); checkit { if($_[0] && $_[1]) { if($_[0] $_[1]) { #Here exists the Problem the interpreter alw +ays displays me an error message print"File exists"; } else { print"File doesnt exist"; } } }
Any help is greatly appreciated Thank you Peter

2005-09-09 Retitled by Arunbear, as per Monastery guidelines
Original title: 'Filecheck'

Replies are listed 'Best First'.
Re: Passing file check operators to a function
by sk (Curate) on Sep 08, 2005 at 00:16 UTC
    I have just read through your specification

    Something like this will do?

    #!/usr/bin/perl -w use strict; sub checkit { my $file = shift; return (-e $file && -w _); # the _ is a shortcut for checking on +the same file instead of making another stat call } my $ret = checkit("/home/monk/hello"); if ($ret) { print "File exists with write perm\n" } else { print "File does not exist or no write perm\n"; }

    will let you know shortly why your code does not work. In the mean time check out perldoc -f -X

    Update: First off why do you need to check for exists and write perm? -w would take care of that.

    Why do you think your -e,-w works?  if (-e,-w $file) does not do  if (-e $file && -w $file) The comma operator just returns the last value evaluated. So it basically will do -w $file and tell you the answer. It might work out but if you turn on warnings you will notice -e works on uninit value as it is looking for $_. If you have set $_ elesewhere it makes things worse as it is not doing what you wanted

     $_[0] && $_[1] in your if statement just checks if the values  $_[0] and $_[1] for true/false. It does not evaluate the expression. Besides  if ($_[0] $_[1]) is not a valid syntax

    Hope this helps!

    cheers

    SK

Re: Passing file check operators to a function
by GrandFather (Saint) on Sep 08, 2005 at 00:52 UTC

    The following does what you would like, although I'd not recommend this as anything other than a learning exercise. In particular if (-e $filename && -w _) is more efficient than hitting on the file system for each test.

    use strict; use warnings; my $filename = "c:\\myfile.txt"; checkit ("-e,-w", $filename) ? print "File $filename exists and is writeable" : print "File $filename does not exist or is not writeable"; sub checkit { my ($tests, $filename) = @_; my @testList = split ",", $tests; for (@testList) { return 0 if ! eval ("$_ '$filename'"); } return 1; }

    Note that eval is used to perform the actual test and split is used to generate a list of tests to be performed.


    Perl is Huffman encoded by design.
      More mods to Grandfather's code to avoid the ugly eval:
      sub checkit { my ($tests, $filename) = @_; my %TestCode=( "-e" => sub{-e $_[0] } , "-w" => sub{-w $_[0] } , "-d" => sub{-d $_[0] } , ); my @testList = split ",", $tests; for (@testList){ exists $TestCode{$_} or return 0; $TestCode{$_}->($filename) or return 0; } return 1; # Passed all tests }
      (Untested)

      Yes, as others have shown, more optimization is possible to avoid multiple stat calls for the same file - the point of THIS post was to avoid the eval.

           "Man cannot live by bread alone...
               He'd better have some goat cheese and wine to go with it!"

Re: Passing file check operators to a function
by polettix (Vicar) on Sep 08, 2005 at 01:59 UTC
    GrandFather gave you the idea for the general case, but I'd note that -w implies -e, so you only need to test for writeability. Moreover, you'd probably make the printed message parametric as well, otherwise it will make sense only when you pass "-e" (as sk implicitly notes changing the message).

    Just 2c,

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
Re: Passing file check operators to a function
by smartnezz (Initiate) on Sep 08, 2005 at 02:47 UTC
    Thanks you all, In deed Grandfather gave me exactly what I'm lookin for... I will make sure to provide the right permission operators on the functin call.

    Can I apply something similar to check if a certain Directory exists and I also have permissions to create a new file in this Directory?

    Peter

      On unix, the same test on a directory name will indicate you can create a file in the directory. You need write permission on the directory inode to insert a new file's metadata. You may want to test -d where -e is tested above, just to verify it's a directory.

      I don't know whether the win32 file tests emulate that or not.

      After Compline,
      Zaxo

      Modified GrandFather's code a bit so that you don't have to loop through to test

      sub checkit { my ($tests, $filename) = @_; my @testList = split ",", $tests; my $teststr = shift(@testList) . " '" . $filename . "'" . " && " . join (' _ && ', @testList) . " _"; return eval ("($teststr)"); return 1; }

      Not very clean but at least it saves you too many stat calls.