Tree-Navigator

 view release on metacpan or  search on metacpan

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

package Tree::Navigator::Node::Perl::Ref;
use utf8;
use Moose;
extends 'Tree::Navigator::Node';

use Scalar::Util     qw/reftype blessed/;
use List::Util       qw/min/;
use Params::Validate qw/validate HASHREF ARRAYREF SCALARREF/;
use namespace::autoclean;

use constant MAX_CHILDREN => 99;

sub MOUNT {
  my ($class, $mount_args) = @_;
  my @mount_point = %{$mount_args->{mount_point} || {}};
  $mount_args->{mount_point} = validate(@mount_point , {
    ref     => {type => HASHREF | ARRAYREF},
    exclude => {type => SCALARREF, isa => 'Regexp', optional => 1},
   });
}


sub _find_ref {
  my $self  = shift;
  my $path = $self->path || "" ;
  my $ref = $self->mount_point->{ref};
  
  foreach my $fragment (split m[/], $path) {
    my $reftype = reftype $ref;
    if ($reftype eq 'ARRAY') {
      $ref = $ref->[$fragment];
    }
    elsif ($reftype eq 'HASH') {
      $ref = $ref->{$fragment};
    }
    elsif ($reftype eq 'SCALAR' || $reftype eq 'REF') {
      $ref = $$ref;
    }
    else {
      die "no such path in data : '$path'";
    }
  }

  return $ref;
}


# inner hashrefs, arrayrefs and scalarrefs are considered 'children';
# other data are considered 'attributes'
sub _ref_is_child {
  my $ref = shift;
  my $reftype = reftype $ref || ''; 
  return $reftype =~ /^(?:HASH|ARRAY|SCALAR|REF)$/;
}


sub _children {
  my $self = shift;
  $self->_find_children_and_attrs;
  return $self->{children};
}

sub _attributes {
  my $self = shift;
  $self->_find_children_and_attrs;
  return $self->{attributes};
}

sub _find_children_and_attrs {
  my $self  = shift;
  my $ref = $self->_find_ref;
  my @children;
  my %attrs;

  my $reftype = reftype $ref;
  if ($reftype eq 'ARRAY') { 
    my @indices = 0 .. min($#$ref, MAX_CHILDREN);
    for my $i (@indices) {
      my $val = $ref->[$i];
      if (_ref_is_child($val)) {
        push @children, $i
      } else {
        $attrs{$i} = $val;
      }
    }
  }
  elsif ($reftype eq 'HASH')  {
    my @keys = keys %$ref;



( run in 0.539 second using v1.01-cache-2.11-cpan-5511b514fd6 )