File-Fu

 view release on metacpan or  search on metacpan

lib/File/Fu/Dir.pm  view on Meta::CPAN

  $self = $self->clone;
  push(@{$self->{dirs}}, @{$newbits{dirs}});
  $self;
} # end subroutine subdir definition
########################################################################

=head2 part

Returns the $i'th part of the directory list.

  my $part = $dir->part($i);

$dir->part(-1) is like $dir->basename, but not an object and not quite
like File::Basename::basename() when it comes to the / directory.

=cut

sub part {
  my $self = shift;
  my ($i) = @_;
  return($self->{dirs}[$i]);
} # end subroutine part definition
########################################################################

=head2 end

Shorthand for part(-1);

=cut

sub end {shift->part(-1)};

=head2 parts

Retrieve the inner list of the directory's parts.

  my @parts = $dir->parts;

  my @parts = $dir->parts(0..2);

The returned parts will be contiguous, but the request can be a
two-element list (and can also start or end at negative indices.)

  my @parts = $dir->parts(3, 7);

  my @parts = $dir->parts(3, -1);

  my @parts = $dir->parts(-5, -1);

=cut

sub parts {
  my $self = shift;
  my @want = @_;
  @want or return(@{$self->{dirs}});
  if(@want == 2) {
    foreach my $end (@want) {
      $end = $#{$self->{dirs}} + 1 + $end if($end < 0);
    }
    if($want[0] > $want[1]) {
      croak("first endpoint '$want[0]' is after last '$want[1]'");
    }
    @want = $want[0]..$want[1];
  }
  # TODO else check contiguity?
  return(@{$self->{dirs}}[@want]);
} # end subroutine parts definition
########################################################################

=head2 slice

Returns a new dir object as the return of parts().

  my $slice = $dir->slice(0);

  my $slice = $dir->slice(0,3);

=cut

sub slice {
  my $self = shift;
  $self = $self->clone;
  @{$self->{dirs}} = $self->parts(@_);
  return($self);
} # end subroutine slice definition
########################################################################

=head2 map

Execute a callback on each part of $dir.  The sub should modify $_ (yes,
this is slightly unlike the map() builtin.)

If $parts is defined as an integer or array reference of integers, it
will be treated as a slice on the directory parts to which the map
should be applied.

  $dir->map(sub {...}, [@parts]);

  $dir &= sub {s/foo$/bar/};

So, to modify only the first directory part:

  $dir->map(sub {s/foo$/bar/}, 0);

=cut

sub map :method {
  my $self = shift;
  my ($sub, $parts) = @_;
  my @parts = defined($parts) ? (ref($parts) ? @$parts : $parts) :
    0..($#{$self->{dirs}});
  # TODO actually use the parts() code for this
  # warn "@parts"; 
  foreach my $dir (@{$self->{dirs}}[@parts]) {
    local $_ = $dir;
    $sub->();
    $dir = $_;
  }
  $self;
} # end subroutine map definition
########################################################################



( run in 0.649 second using v1.01-cache-2.11-cpan-e1769b4cff6 )