and the C is C. #pod #pod This works even on C with drives and UNC volumes: #pod #pod path("C:/")->is_rootdir; # true #pod path("//server/share/")->is_rootdir; #true #pod #pod Current API available since 0.038. #pod #pod =cut sub is_rootdir { my ($self) = @_; $self->_splitpath unless defined $self->[DIR]; return $self->[DIR] eq '/' && $self->[FILE] eq ''; } #pod =method iterator #pod #pod $iter = path("/tmp")->iterator( \%options ); #pod #pod Returns a code reference that walks a directory lazily. Each invocation #pod returns a C object or undef when the iterator is exhausted. #pod #pod $iter = path("/tmp")->iterator; #pod while ( $path = $iter->() ) { #pod ... #pod } #pod #pod The current and parent directory entries ("." and "..") will not #pod be included. #pod #pod If the C option is true, the iterator will walk the directory #pod recursively, breadth-first. If the C option is also true, #pod directory links will be followed recursively. There is no protection against #pod loops when following links. If a directory is not readable, it will not be #pod followed. #pod #pod The default is the same as: #pod #pod $iter = path("/tmp")->iterator( { #pod recurse => 0, #pod follow_symlinks => 0, #pod } ); #pod #pod For a more powerful, recursive iterator with built-in loop avoidance, see #pod L. #pod #pod See also L. #pod #pod Current API available since 0.016. #pod #pod =cut sub iterator { my $self = shift; my $args = _get_args( shift, qw/recurse follow_symlinks/ ); my @dirs = $self; my $current; return sub { my $next; while (@dirs) { if ( ref $dirs[0] eq 'Path::Tiny' ) { if ( !-r $dirs[0] ) { # Directory is missing or not readable, so skip it. There # is still a race condition possible between the check and # the opendir, but we can't easily differentiate between # error cases that are OK to skip and those that we want # to be exceptions, so we live with the race and let opendir # be fatal. shift @dirs and next; } $current = $dirs[0]; my $dh; opendir( $dh, $current->[PATH] ) or $self->_throw( 'opendir', $current->[PATH] ); $dirs[0] = $dh; if ( -l $current->[PATH] && !$args->{follow_symlinks} ) { # Symlink attack! It was a real dir, but is now a symlink! # N.B. we check *after* opendir so the attacker has to win # two races: replace dir with symlink before opendir and # replace symlink with dir before -l check above shift @dirs and next; } } while ( defined( $next = readdir $dirs[0] ) ) { next if $next eq '.' || $next eq '..'; my $path = $current->child($next); push @dirs, $path if $args->{recurse} && -d $path && !( !$args->{follow_symlinks} && -l $path ); return $path; } shift @dirs; } return; }; } #pod =method lines, lines_raw, lines_utf8 #pod #pod @contents = path("/tmp/foo.txt")->lines; #pod @contents = path("/tmp/foo.txt")->lines(\%options); #pod @contents = path("/tmp/foo.txt")->lines_raw; #pod @contents = path("/tmp/foo.txt")->lines_utf8; #pod #pod @contents = path("/tmp/foo.txt")->lines( { chomp => 1, count => 4 } ); #pod #pod Returns a list of lines from a file. Optionally takes a hash-reference of #pod options. Valid options are C, C and C. #pod #pod If C is provided, it will be set on the handle prior to reading. #pod #pod If a positive C is provided, that many lines will be returned from the #pod start of the file. If a negative C is provided, the entire file will be #pod read, but only C will be kept and returned. If C #pod exceeds the number of lines in the file, all lines will be returned. #pod #pod If C is set, any end-of-line character sequences (C, C, or #pod C) will be removed from the lines returned. #pod #pod Because the return is a list, C in scalar context will return the number #pod of lines (and throw away the data). #pod #pod $number_of_lines = path("/tmp/foo.txt")->lines; #pod #pod C is like C with a C of C<:raw>. We use C<:raw> #pod instead of C<:unix> so PerlIO buffering can manage reading by line. #pod #pod C is like C with a C of C<:raw:encoding(UTF-8)> #pod (or C<:raw:utf8_strict> with L). If L #pod 0.58+ is installed, a raw, unbuffered UTF-8 slurp will be done and then the #pod lines will be split. This is actually faster than relying on #pod IO layers, though a bit memory intensive. If memory use is a #pod concern, consider C and iterating directly on the handle. #pod #pod See also L
. #pod #pod This works even on C with drives and UNC volumes: #pod #pod path("C:/")->is_rootdir; # true #pod path("//server/share/")->is_rootdir; #true #pod #pod Current API available since 0.038. #pod #pod =cut sub is_rootdir { my ($self) = @_; $self->_splitpath unless defined $self->[DIR]; return $self->[DIR] eq '/' && $self->[FILE] eq ''; } #pod =method iterator #pod #pod $iter = path("/tmp")->iterator( \%options ); #pod #pod Returns a code reference that walks a directory lazily. Each invocation #pod returns a C object or undef when the iterator is exhausted. #pod #pod $iter = path("/tmp")->iterator; #pod while ( $path = $iter->() ) { #pod ... #pod } #pod #pod The current and parent directory entries ("." and "..") will not #pod be included. #pod #pod If the C option is true, the iterator will walk the directory #pod recursively, breadth-first. If the C option is also true, #pod directory links will be followed recursively. There is no protection against #pod loops when following links. If a directory is not readable, it will not be #pod followed. #pod #pod The default is the same as: #pod #pod $iter = path("/tmp")->iterator( { #pod recurse => 0, #pod follow_symlinks => 0, #pod } ); #pod #pod For a more powerful, recursive iterator with built-in loop avoidance, see #pod L. #pod #pod See also L. #pod #pod Current API available since 0.016. #pod #pod =cut sub iterator { my $self = shift; my $args = _get_args( shift, qw/recurse follow_symlinks/ ); my @dirs = $self; my $current; return sub { my $next; while (@dirs) { if ( ref $dirs[0] eq 'Path::Tiny' ) { if ( !-r $dirs[0] ) { # Directory is missing or not readable, so skip it. There # is still a race condition possible between the check and # the opendir, but we can't easily differentiate between # error cases that are OK to skip and those that we want # to be exceptions, so we live with the race and let opendir # be fatal. shift @dirs and next; } $current = $dirs[0]; my $dh; opendir( $dh, $current->[PATH] ) or $self->_throw( 'opendir', $current->[PATH] ); $dirs[0] = $dh; if ( -l $current->[PATH] && !$args->{follow_symlinks} ) { # Symlink attack! It was a real dir, but is now a symlink! # N.B. we check *after* opendir so the attacker has to win # two races: replace dir with symlink before opendir and # replace symlink with dir before -l check above shift @dirs and next; } } while ( defined( $next = readdir $dirs[0] ) ) { next if $next eq '.' || $next eq '..'; my $path = $current->child($next); push @dirs, $path if $args->{recurse} && -d $path && !( !$args->{follow_symlinks} && -l $path ); return $path; } shift @dirs; } return; }; } #pod =method lines, lines_raw, lines_utf8 #pod #pod @contents = path("/tmp/foo.txt")->lines; #pod @contents = path("/tmp/foo.txt")->lines(\%options); #pod @contents = path("/tmp/foo.txt")->lines_raw; #pod @contents = path("/tmp/foo.txt")->lines_utf8; #pod #pod @contents = path("/tmp/foo.txt")->lines( { chomp => 1, count => 4 } ); #pod #pod Returns a list of lines from a file. Optionally takes a hash-reference of #pod options. Valid options are C, C and C. #pod #pod If C is provided, it will be set on the handle prior to reading. #pod #pod If a positive C is provided, that many lines will be returned from the #pod start of the file. If a negative C is provided, the entire file will be #pod read, but only C will be kept and returned. If C #pod exceeds the number of lines in the file, all lines will be returned. #pod #pod If C is set, any end-of-line character sequences (C, C, or #pod C) will be removed from the lines returned. #pod #pod Because the return is a list, C in scalar context will return the number #pod of lines (and throw away the data). #pod #pod $number_of_lines = path("/tmp/foo.txt")->lines; #pod #pod C is like C with a C of C<:raw>. We use C<:raw> #pod instead of C<:unix> so PerlIO buffering can manage reading by line. #pod #pod C is like C with a C of C<:raw:encoding(UTF-8)> #pod (or C<:raw:utf8_strict> with L). If L #pod 0.58+ is installed, a raw, unbuffered UTF-8 slurp will be done and then the #pod lines will be split. This is actually faster than relying on #pod IO layers, though a bit memory intensive. If memory use is a #pod concern, consider C and iterating directly on the handle. #pod #pod See also L
and the C is C. This works even on C with drives and UNC volumes: path("C:/")->is_rootdir; # true path("//server/share/")->is_rootdir; #true Current API available since 0.038. =head2 iterator $iter = path("/tmp")->iterator( \%options ); Returns a code reference that walks a directory lazily. Each invocation returns a C object or undef when the iterator is exhausted. $iter = path("/tmp")->iterator; while ( $path = $iter->() ) { ... } The current and parent directory entries ("." and "..") will not be included. If the C option is true, the iterator will walk the directory recursively, breadth-first. If the C option is also true, directory links will be followed recursively. There is no protection against loops when following links. If a directory is not readable, it will not be followed. The default is the same as: $iter = path("/tmp")->iterator( { recurse => 0, follow_symlinks => 0, } ); For a more powerful, recursive iterator with built-in loop avoidance, see L. See also L. Current API available since 0.016. =head2 lines, lines_raw, lines_utf8 @contents = path("/tmp/foo.txt")->lines; @contents = path("/tmp/foo.txt")->lines(\%options); @contents = path("/tmp/foo.txt")->lines_raw; @contents = path("/tmp/foo.txt")->lines_utf8; @contents = path("/tmp/foo.txt")->lines( { chomp => 1, count => 4 } ); Returns a list of lines from a file. Optionally takes a hash-reference of options. Valid options are C, C and C. If C is provided, it will be set on the handle prior to reading. If a positive C is provided, that many lines will be returned from the start of the file. If a negative C is provided, the entire file will be read, but only C will be kept and returned. If C exceeds the number of lines in the file, all lines will be returned. If C is set, any end-of-line character sequences (C, C, or C) will be removed from the lines returned. Because the return is a list, C in scalar context will return the number of lines (and throw away the data). $number_of_lines = path("/tmp/foo.txt")->lines; C is like C with a C of C<:raw>. We use C<:raw> instead of C<:unix> so PerlIO buffering can manage reading by line. C is like C with a C of C<:raw:encoding(UTF-8)> (or C<:raw:utf8_strict> with L). If L 0.58+ is installed, a raw, unbuffered UTF-8 slurp will be done and then the lines will be split. This is actually faster than relying on IO layers, though a bit memory intensive. If memory use is a concern, consider C and iterating directly on the handle. See also L
. This works even on C with drives and UNC volumes: path("C:/")->is_rootdir; # true path("//server/share/")->is_rootdir; #true Current API available since 0.038. =head2 iterator $iter = path("/tmp")->iterator( \%options ); Returns a code reference that walks a directory lazily. Each invocation returns a C object or undef when the iterator is exhausted. $iter = path("/tmp")->iterator; while ( $path = $iter->() ) { ... } The current and parent directory entries ("." and "..") will not be included. If the C option is true, the iterator will walk the directory recursively, breadth-first. If the C option is also true, directory links will be followed recursively. There is no protection against loops when following links. If a directory is not readable, it will not be followed. The default is the same as: $iter = path("/tmp")->iterator( { recurse => 0, follow_symlinks => 0, } ); For a more powerful, recursive iterator with built-in loop avoidance, see L. See also L. Current API available since 0.016. =head2 lines, lines_raw, lines_utf8 @contents = path("/tmp/foo.txt")->lines; @contents = path("/tmp/foo.txt")->lines(\%options); @contents = path("/tmp/foo.txt")->lines_raw; @contents = path("/tmp/foo.txt")->lines_utf8; @contents = path("/tmp/foo.txt")->lines( { chomp => 1, count => 4 } ); Returns a list of lines from a file. Optionally takes a hash-reference of options. Valid options are C, C and C. If C is provided, it will be set on the handle prior to reading. If a positive C is provided, that many lines will be returned from the start of the file. If a negative C is provided, the entire file will be read, but only C will be kept and returned. If C exceeds the number of lines in the file, all lines will be returned. If C is set, any end-of-line character sequences (C, C, or C) will be removed from the lines returned. Because the return is a list, C in scalar context will return the number of lines (and throw away the data). $number_of_lines = path("/tmp/foo.txt")->lines; C is like C with a C of C<:raw>. We use C<:raw> instead of C<:unix> so PerlIO buffering can manage reading by line. C is like C with a C of C<:raw:encoding(UTF-8)> (or C<:raw:utf8_strict> with L). If L 0.58+ is installed, a raw, unbuffered UTF-8 slurp will be done and then the lines will be split. This is actually faster than relying on IO layers, though a bit memory intensive. If memory use is a concern, consider C and iterating directly on the handle. See also L