Provided by: libbadger-perl_0.16-2_all bug

NAME

       Badger::Filesystem::Visitor - visitor for traversing filesystems

SYNOPSIS

           use Badger::Filesystem 'FS';

           my $controls = {
               files       => '*.pm',           # collect all *.pm files
               dirs        => 0,                # ignore dirs
               in_dirs     => 1,                # but do look in dirs for more files
               not_in_dirs => ['.svn', '.git'], # don't look in these dirs
           };

           my @files = FS
               ->dir('/path/to/dir')
               ->visit($controls)
               ->collect;

DESCRIPTION

       The Badger::Filesystem::Visitor module implements a base class visitor object which can be
       used to traverse filesystems.

       The most common use of a visitor is to walk a filesystem and locate files and directories
       matching (or not matching) a particular set of criteria (e.g. file name, type, size, etc).
       The Badger::Filesystem::Visitor module provides a number of configuration options to
       assist in these common tasks. For more complex operations, you can subclass the module to
       create your own custom visitors.

       The easiest way to create and use a visitor is to call the visit() method on any of the
       Badger::Filesystem objects. In most cases, you'll want to call it against a
       Badger::Filesystem::Directory object, but there's nothing to stop you from calling it
       against a Badger::Filesystem::File object (although your visitor won't have anywhere to
       visitor beyond that single file so it doesn't serve any practical purpose).  If you call
       it against a top-level Badger::Filesystem object then it will be applied to the root
       directory of the filesystem.

           use Badger::Filesystem 'Dir';

           my $dir     = Dir('/path/to/search/dir');
           my $visitor = $dir->visit( files => 1, dirs => 0 );
           my $collect = $visitor->collect;

       The visit() method will first create a "Badger::Filesystem::Visitor" object by delegating
       to the Badger::Filesystem visitor() method. This configures the new visitor using any
       parameters passed as arguments, specified either as a list or reference to a hash array of
       named parameters. If no parameters are specified then the defaults are used.  The
       visitor's visit() method is then called, passing the Badger::Filesystem::Directory object
       as an argument.  And so begins the visitor's journey into the filesystem...

       The configuration parameters are used to define what the visitor should collect on its
       travels.  Here are some examples.

           $dir->visit(
               files => 1,                 # collect all files
               dirs  => 0,                 # ignore all dirs
           );

           $dir->visit(
               files => '*.pm',            # collect all .pm files
               dirs  => 0,                 # ignore all dirs
           );

           $dir->visit(
               files   => '*.pm',          # as above, no dirs are collected
               dirs    => 0,               # but we do enter into them to
               in_dirs => 1,               # find more files
           );

           $dir->visit(
               files       => '*.pm',      # collect *.pm files
               dirs        => 0,           # don't collect dirs
               in_dirs     => 1,           # do recurse into them
               not_in_dirs => '.svn',      # but don't look in .svn dirs
           );

           $dir->visit(
               files   => 'foo'            # find all files named 'foo'
               dirs    => qr/ba[rz]/,      # and all dirs named 'bar' or 'baz'
               in_dirs => 1,               # recurse into subdirs
           );

       You can also define subroutines to filter the files and/or directories that you're
       interested in. The first argument passed to the subroutine is the Badger::Filesystem::File
       or Badger::Filesystem::Directory object being visited.  The second argument is a reference
       to the visitor object.

       In the following example, we collect files that are smaller than 420 bytes in size, and
       directories that contain a metadata.yaml file.

           $dir->visit(
               files   => sub { shift->size < 420 },
               dirs    => sub { shift->file('metadata.yaml')->exists }
               in_dirs => 1,
           );

       You can also specify a reference to a list of items, each of which can be a simple flag
       (0/1), a name to match, regular expression or subroutine reference.  Each will be tested
       in turn until the first one matches.  If none match then the file or directory will be
       ignored.

           $dir->visit(
               files   => ['foo', qr/wiz/i, \&my_file_sub ],
               dirs    => [ qr/ba[rz]/, \&my_dir_sub ],
               in_dirs => 1,
           );

       In addition to the inclusive matches show above, you can also tell the visitor what to
       exclude. You can use any of the same pattern specifications as for the inclusive options
       (0/1 flags, names, regexen, subroutines, or list refs containing any of the above).

           $dir->visit(
               no_files    => '*.bak',
               no_dirs     => ['tmp', qr/backup/i],
               not_in_dirs => ['.svn', '.DS_Store'],
           );

       When the visit is done, the collect() method can be called to return a list (in list
       context) or reference to a list (in scalar context) of the items that were collected.  The
       list will contain Badger::Filesystem::File and Badger::Filesystem::Directory objects.

           my $collect = $visitor->collect;        # list ref in scalar context
           my @collect = $visitor->collect;        # list in list context

CONFIGURATION OPTIONS

       NOTE: I'm planning the add the 'accept', 'ignore', 'enter', and 'leave' aliases for
       'files', 'no_files', 'in_dirs' and 'not_in_dirs'.  Can't think of better names for 'dirs'
       and 'no_dirs' though...

   files / accept (todo)
       A pattern specifier indicating the files that you want to match.

   no_files / ignore (todo)
       A pattern specifier indicating the files that you don't want to match.

   dirs / directories
       A pattern specifier indicating the directories that you want to match.

   no_dirs / no_directories
       A pattern specifier indicating the directories that you don't want to match.

   in_dirs / in_directories / enter (todo)
       A pattern specifier indicating the directories that you want to enter to search for
       further files and directories.

   not_in_dirs / not_in_directories / leave (todo)
       A pattern specifier indicating the directories that you don't want to enter to search for
       further files and directories.

   at_file
       A reference to a subroutine that you want called whenever a file of interest (i.e. one
       that is included by files and not excluded by no_files) is visited.  The subroutine is
       passed a reference to the visitor object and a reference to a Badger::Filesystem::File
       object representing the file.

           $dir->visit(
               at_file => sub {
                   my ($visitor, $file) = @_;
                   print "visiting file: ", $file->name, "\n";
               }
           );

   at_dir / at_directory
       A reference to a subroutine that you want called whenever a directory of interest (i.e.
       one that is included by dirs and not excluded by no_dirs) is visited. The subroutine is
       passed a reference to the visitor object and a reference to a
       Badger::Filesystem::Directory object representing the directory.

           $dir->visit(
               at_dir => sub {
                   my ($visitor, $dir) = @_;
                   print "visiting dir: ", $dir->name, "\n";
               }
           );

       If the function returns a true value then the visitor will continue to visit any files or
       directories within it according to it's usual rules (i.e. if the directory is listed in a
       not_in_dirs rule then it won't be entered).  If the function returns a false value then
       the directory will be skipped.

METHODS

   new(\%params)
       Constructor method to create a new "Badger::Filesystem::Visitor".

TRAVERSAL METHODS

   visit($node)
       General purpose dispatch method to visit any node. This method calls the accept() method
       on the $node, passing the visitor $self reference as an argument. The $node will then call
       back to the correct method for the node type (e.g. visit_file() or visit_dir())

   visit_path($path)
       This method is called to visit base class Badger::Filesystem::Path objects. It doesn't do
       anything useful at present, but probably should.

   visit_file($file)
       This method is called to visit a Badger::Filesystem::File object.

   visit_directory($dir) / visit_dir($dir)
       This method is called to visit a Badger::Filesystem::Directory object.

   visit_directory_children($dir) / visit_dir_kids($dir)
       This method is called to visit the children of a Badger::Filesystem::Directory object.

SELECTION METHODS

   accept_file($file)
       This method applies any selection rules defined for the visitor to determine if a file
       should be collected or not.  It returns a true value if it should, or a false value if
       not.

   accept_directory($dir) / accept_dir($dir)
       This method applies any selection rules defined for the visitor to determine if a
       directory should be collected or not. It returns a true value if it should, or a false
       value if not.

   enter_directory($dir) / enter_dir($dir)
       This method applies any selection rules defined for the visitor to determine if a
       directory should be entered or not. It returns a true value if it should, or a false value
       if not.

   filter($type,$method,$item)
       This is a general purpose method which implements the selection algorithm for the above
       methods.  For example, the accept_file() method is implemented as:

           return $self->filter( files    => name => $file )
             && ! $self->filter( no_files => name => $file );

       The first argument provides the name of the configuration parameter which defines the
       filter specification. The second argument is the name of the file/directory method that
       returns the value that should be compared (in this case, the file or directory name). The
       third argument is the file or directory object itself.

COLLECTION METHODS

   collect_file($file)
       This method is called by the visitor when a file is accepted by the accept_file() method.
       If an at_file handler is defined then it is called, passing a reference to the visitor and
       the file being visited.  If the handler returns a true value then the method goes on to
       call collect().  Otherwise it returns immediately.

       If no at_file handler is defined then the method delegates to collect().

   collect_directory($dir) / collect_dir($dir)
       This method is called by the visitor when a directory is accepted by the
       accept_directory() method. If an at_directory handler is defined then it is called,
       passing a reference to the visitor and the directory being visited as arguments. If the
       handler returns a true value then the method goes on to call collect(). Otherwise it
       returns immediately and short-circuits any further visits to files or directories
       contained within it.

       If no at_directory handler is defined then the method delegates to collect().

   collect(@items)
       This method is used by the visitor to collect items of interest.  Any arguments passed are
       added to the internal "collect" list.

           $visitor->collect($this, $that);

       The list of collected items is returned in list context, or a reference to a list in
       scalar context.

           my $collect = $visitor->collect;
           my @collect = $visitor->collect;

   identify(%items)
       This method is similar to collect() but is used to construct a lookup table for
       identifying files and directories by name. In fact, it's currently not currently used for
       anything, but may be one day RSN.

AUTHOR

       Andy Wardley <http://wardley.org/>

COPYRIGHT

       Copyright (C) 2005-2009 Andy Wardley. All rights reserved.

SEE ALSO

       Badger::Filesystem