1

I am currently learning perl and when I encountered a piece of code explainng how to traverse a directory tree using recursive subroutines. This is the code in question

use strict;
use warnings;
use 5.010;
my $path = shift || '.';
traverse($path);

sub traverse {
my ($thing) = @_;

    return if not -d $thing;
    opendir my $dh, $thing or die;
    while (my $sub = readdir $dh) {
        next if $sub eq '.' or $sub eq '..';
        say "$thing/$sub";
        traverse("$thing/$sub");
    }
    close $dh;
    return;
}

I understood the subroutine and how it works, however I did not understand this statement: (my $path = shift || '.';) I know that it is the variable that is passed to the subroutine, but I do not know what value it takes. Thanks in advance.

Hadi Nounou
  • 131
  • 1
  • 13

2 Answers2

2

Outside of a subroutine, shift with no arguments does shift @ARGV, getting the first command-line argument.

The || operator returns the left side if the left side is truthy or the right side if the left side is falsy. So if the shift succeeded, $path probably gets set to the command-line argument. If @ARGV was empty, shift returns undef, so $path will get set to '.' instead.

Note this will do the wrong thing if for example you have a directory named "0" and try to run myscript.pl 0.

aschepler
  • 70,891
  • 9
  • 107
  • 161
0

That statement says: "pull the next element from the argument list and assign it to $path. If there is no argument in the list, or the first element evaluates to false, put . in $path instead".

shift, when used in the main part of a program and not in a subroutine uses @ARGV (command line arguments) as its list to shift elements off of.

use warnings;
use strict;

my $x = shift || 'bye';

print "$x\n";

Run it:

$ perl script.pl
bye

$ perl script.pl hi
hi
stevieb
  • 9,065
  • 3
  • 26
  • 36