in reply to Help with exercise

Hi codeKnight,

In addition to what Anonymous Monk said, I would comment that this conditional statement:

elsif(($#ARGV+1) < 1) {
is a bit strange. First, it would be simpler to test:
elsif ($#ARGV < 0) {
(Note that if no argument is passed, $#ARGV will be -1.)

Second, if you want to test the number of arguments passed to the program, it is clearer to evaluate @ARGV in scalar context (which gives the number of items in that array):

elsif (@ARGV < 1) { # or, if you prefer an explicitly stated scalar context: elsif (scalar @ARGV < 1) {
Last, but not least, this conditional statement will never be true because, if you don't pass any argument, this statement will not be executed: the program will die with the first conditional
if(! -e "$Dir") {
In fact, it is quite strange to check if an argument is passed after having checked whether the value of the argument is a valid directory.

So if you want to check that at least one argument is being passed to the program, you should do it first.

Also, it is a bit useless to check for the existence of $Dir and then whether it is a valid directory (unless you want to print a different message in that case); you can check directly that it is a valid directory.

So, this program could be rewritten as:

use strict; use warnings; die "Please supply an argument to the program" if @ARGV < 1; my $dir = shift; die "Please try again with a valid directory.\n" unless -d $dir; # Change to user selected location chdir $dir; mkdir "FirstSubDir"; mkdir "SecondSubDir";

Replies are listed 'Best First'.
Re^2: Help with exercise
by NetWallah (Canon) on Sep 23, 2017 at 17:21 UTC
    In keeping with your recommended best practices of error checking at each step, the main code should be
    chdir $dir or die "ERROR: Could not change directory to $dir +"; mkdir "FirstSubDir" or die "ERROR creating FirstSubdir:$!"; mkdir "SecondSubDir" or die "ERROR creating SecondSubDir:$!";

                    All power corrupts, but we need electricity.

      of course once we get into checking the returns, we may find chdir does all the testing we need already ...

      use strict; use warnings; use Cwd; my $dir = shift; chdir $dir or die "Couldn't chdir $dir: $!\n"; print "OK, in ". getcwd . "\n";

      And the outut

      # ./change.pl Downloads/ OK, in /home/Random/Downloads # ./perl change.pl foo Couldn't chdir foo: No such file or directory # ./mkdir bar # ./chmod 000 bar # ./perl change.pl bar Couldn't chdir bar: Permission denied

      Cheers,
      R.

      Pereant, qui ante nos nostra dixerunt!
      Yes, agreed ++. Here, I wanted to keep it simple in the context of an exercise.

      Although, to tell the full truth, I am not sure I would really check the chdir return status after I have checked that $dir contains a valid directory entry in the current directory (I know it might still fail for various reasons, such as missing privileges, but this is quite unlikely in my context and, sometimes, there is a trade-off between code complexity and coding efficiency). Or I might probably use the autodie module in such a context with a lot of system calls.

      Update: or, as suggested by Random_Walk, we might go the other way around and let chdir do the checks.

        BTW, mkpath from Path::Tiny does it all, less or more:

        "...Errors will be trapped and an exception thrown. Returns the list of directories created or an empty list if the directories already exist, just like make_path."
        karls-mac-mini:monks karl$ perl -MPath::Tiny -E 'say path (q(/foo/bla) +)->mkpath' /Users/karl/Desktop/bla karls-mac-mini:monks karl$ perl -MPath::Tiny -E 'say path (q(/foo/bla) +)->mkpath' karl-mac-mini:monks karl$

        Regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help