Commits

Anonymous committed d59516f

Switched the chained objects recursion to one _dir_stack().

Comments (0)

Files changed (2)

lib/File/Find/Object.pm

 
 use strict;
 use warnings;
+
 use File::Find::Object::internal;
 
 our $VERSION = '0.0.3';
 sub new {
     my ($class, $options, @files) = @_;
     my $tree = {
-        _father => undef,
-        _current => undef,
         files => [ @files ],
         ind => -1,
         
         followlink => $options->{followlink},
         filter => $options->{filter},
         callback => $options->{callback},
+        _dir_stack => [],
     };
     bless($tree, $class);
 }
 
+sub _dir_stack
+{
+    my $self = shift;
+    if (@_)
+    {
+        $self->{_dir_stack} = shift;
+    }
+    return $self->{_dir_stack};
+}
+
 sub _top
 {
     my $self = shift;
 #    printf STDERR "destroy `%s'\n", $self->{dir} || "--";
 }
 
+sub _current
+{
+    my $self = shift;
+    return $self->_dir_stack()->[-1] || $self;
+}
+
 sub next {
     my ($self) = @_;
     while (1) {
-        my $current = $self->{_current} || $self;
+        my $current = $self->_current();
         $current->_process_current and return $self->{item} = $current->current_path;
-        $current = $self->{_current} || $self;
+        $current = $self->_current();
         if(!$self->movenext) {
             $current->me_die and return $self->{item} = undef;
         }
     $self->{item}
 }
 
+sub _top_father
+{
+    my $self = shift;
+    return ($self->_dir_stack->[-2] || $self);
+}
+
+sub _father
+{
+    my $self = shift;
+    if (!defined($self->{idx}))
+    {
+        return undef;
+    }
+    elsif ($self->{idx} >= 1)
+    {
+        return $self->_top->_dir_stack()->[$self->{idx}-1];
+    }
+    else
+    {
+        return $self->_top();
+    }
+}
+
 sub _movenext_with_current
 {
     my $self = shift;
-    if ($self->{_current}->{currentfile} = shift(@{$self->{_current}->{_father}->{_files}})) {
-        $self->{_current}->{_action} = {};
+    if ($self->_current->{currentfile} = 
+        shift(@{$self->_current->_father->{_files}})
+       )
+    {
+        $self->_current->{_action} = {};
         return 1;
     } else {
         return 0;
 
 sub movenext {
     my ($self) = @_;
-    if (defined($self->{_current}))
+    if (@{$self->_dir_stack()})
     {
         return $self->_movenext_with_current();
     }
 
 sub become_default {
     my ($self) = @_;
-    $self->{_current} = undef;
-}
-
-sub set_current {
-    my ($self, $current) = @_;
-    $self->{_current} = $current;
+    @{$self->_dir_stack()} = ();
 }
 
 # Return true if there is somthing next
             
         if ($_ eq 'b') {
             $self->check_subdir or next;
-            my $newtree = File::Find::Object::internal->new($self) or next;
-            $self->set_current($newtree);
+            push @{$self->_top->_dir_stack()}, File::Find::Object::internal->new($self, scalar(@{$self->_top->_dir_stack()}));
             return 0;
         }
     }
     return 1;
 }
 
-1
-
 __END__
 
 =head1 NAME

lib/File/Find/Object/internal.pm

 
 use strict;
 use warnings;
-use File::Find::Object;
 
 use vars qw(@ISA);
 @ISA = qw(File::Find::Object);
 use File::Spec;
 
 sub new {
-    my ($class, $from) = @_;
+    my ($class, $from, $index) = @_;
     my $self = {
-        _father => $from,
         _top => $from->_top,
         dir => $from->current_path,
+        idx => $index,
     };
 
     bless($self, $class);
 
     $from->{dir} = $self->{dir};
 
-    return $self->{_father}->open_dir ? $self : undef;
+    return $self->_father->open_dir ? $self : undef;
 }
 
 #sub DESTROY {
 
 sub me_die {
     my ($self) = @_;
-    $self->{_father}->become_default;
+    $self->_father()->become_default;
     0
 }
 
 sub become_default {
     my ($self) = @_;
-    $self->_top->{_current} = $self;
-    0
+    while (scalar(@{$self->_top->_dir_stack()}) != $self->{idx} + 1)
+    {
+        pop(@{$self->_top->_dir_stack()});
+    }
+    return 0;
 }
 
-sub set_current {
-    my ($self, $current) = @_;
-    $self->_top->{_current} = $current;
-}
 
 sub current_path {
     my ($self) = @_;
-    my $p = $self->{_father}->{dir};
+    my $p = $self->_father->{dir};
     $p =~ s!/+$!!; #!
     $p .= '/' . $self->{currentfile};
 }
     my @st = stat($self->current_path());
     !-d _ and return 0;
     -l $self->current_path() && !$self->_top->{followlink} and return 0;
-    $st[0] != $self->{_father}->{dev} && $self->_top->{nocrossfs} and return 0;
+    $st[0] != $self->_father->{dev} && $self->_top->{nocrossfs} and return 0;
     my $ptr = $self; my $rc;
-    while($ptr->{_father}) {
-        if($ptr->{_father}->{inode} == $st[1] && $ptr->{_father}->{dev} == $st[0]) {
+    while($ptr->_father) {
+        if($ptr->_father->{inode} == $st[1] && $ptr->_father->{dev} == $st[0]) {
             $rc = 1;
             last;
         }
-        $ptr = $ptr->{_father};
+        $ptr = $ptr->_father;
     }
     if ($rc) {
-        printf(STDERR "Avoid loop $ptr->{_father}->{dir} => %s\n",
+        printf(STDERR "Avoid loop " . $ptr->_father->{dir} . " => %s\n",
             $self->current_path());
         return 0;
     }
     1
 }
 
-1
+1;