Tree-Navigator

 view release on metacpan or  search on metacpan

lib/Tree/Navigator/Node.pm  view on Meta::CPAN


sub child {
  my ($self, $child_name) = @_;
  my $child = $self->mounted_at->{$child_name}
            || $self->_child($child_name)
    or die "no such child: '$child_name' in " . $self->full_path;
  return $child;
}


sub _child {
  my ($self, $child_name) = @_;
  return undef;
}


sub children {
  my $self = shift;
  my $mounted  = $self->mounted;
  my $children = $self->_children;
  return @$mounted, @$children;
}


sub content {
  my $self = shift;
  if (my $fh = $self->{content}) {
    # if the filehandle is already present, rewind it to beginning of file
    $fh->seek(0, 0);
    return $fh;
  }
  else {
    return $self->_content;
  }
}



sub _content {
  my $self = shift;
  return undef;
}

sub content_text {
  my $self = shift;
  my $fh = $self->content;
  return $fh ? join("", <$fh>) : "";
}


#======================================================================
# generic methods
#======================================================================
sub descendent {
  my ($self, $path) = @_;

  # $self is its own descendent if $path is empty
  return $self if ($path // '') eq ''; # NOTE : '0' is a valid nonempty path!

  # otherwise, find the child from initial path segment, and then recurse
  my ($child_name, $subpath) = split m{/}, $path, 2;
  my $child = $self->child($child_name)
    or die "no such child: $child_name";
  return $child->descendent($subpath);
}

sub is_parent { # default implementation; may be optimised in subclasses
  my $self = shift;
  my @children = $self->children;
  return @children ? 1 : 0;
}

sub _join_path {
  my ($self, $path_ini, $path_end) = @_;
  $_ //= '' for $path_ini, $path_end;

  return $path_ini ne '' ? $path_end ne '' ? "$path_ini/$path_end"
                                           : $path_ini
                         : $path_end;
}

sub full_path {
  my $self = shift;

  return $self->_join_path($self->mount_point->{path}, $self->path);
}


sub last_path {
  my $self = shift;
  my $path = $self->full_path;
  $path =~ s[^.*/][];
  return $path;
}

sub subnodes_and_leaves {
  my $self = shift;
  my ($subnodes, $leaves)
    = part {$self->child($_)->is_parent ? 0 : 1} $self->children;
  $_ //= [] for $subnodes, $leaves;
  return ($subnodes, $leaves);
}



#======================================================================
# WORK IN PROGRESS
#======================================================================

sub navigator {
  my $self = shift;
  return $self->mount_point->{navigator};
}

sub data {
  my $self = shift;
  my %data = (attributes   => $self->attributes,
              content_text => $self->content_text);

  foreach my $child_name ($self->children) {
    my $child = $self->child($child_name);



( run in 1.088 second using v1.01-cache-2.11-cpan-71847e10f99 )