
== Rant::FileList

A +FileList+ object is in essence a list of path names. It behaves
similar to an array of strings, but provides useful methods to include
files based on so called "glob" patterns, i.e. strings containing
wildcards and similar special characters.

The examples in this document show how to use the +FileList+ class as
library from other ruby applications/libraries.

To use the <tt>Rant::FileList</tt> class, you must <tt>require
"rant/filelist"</tt> first. This will define the following constants:

Rant::              Module, used as namespace for all Rant code.
Rant::VERSION::     The Rant version in use, e.g. <tt>"0.5.2"</tt>.
Rant::FileList::    The filelist class.
Rant::Sys::         With method +regular_filename+.

It is recommended to *not* <tt>include Rant</tt> at the toplevel for
use in libraries or bigger applications. A better technique is to
assign often used constants to shorter names, e.g.:

    FileList = Rant::FileList

Some method documentations contain an <em>Implementation Note</em>.
These notes are provided for better understanding. The actual
implementation might change.

=== Creating a Rant::FileList

There a five ways to obtain a +FileList+ object:

* <b>Rant::FileList.new</b>

  Creates an empty filelist.

  Examples:

    require 'rant/filelist'

    fl = Rant::FileList.new
    fl.entries                      # => []

    fl.include("*README*")
    fl.entries                      # => ["README", ".README.swp"]


* <b>Rant::FileList[*patterns]</b>

  Create a filelist which contains all file names matching one of
  +patterns+. Each of +patterns+ is a glob pattern as described under
  <em>Glob pattern syntax</em>.

  Per default, all files/directories starting with a dot are ignored,
  unless a pattern explicitely matches names starting with a dot.

  Examples:

    require 'rant/filelist'

    # Create a filelist containing all file names ending in ".c" from
    # the current directory
    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "util.c"]

    # Create a filelist containing the "README" file from the current
    # directory (if it exists) and all files ending in ".rdoc" under
    # the "doc" directory and its subdirectories.
    fl = Rant::FileList["README", "doc/**/*.rdoc"]
    fl.entries                      # => ["README", "doc/foo.rdoc", "doc/html/emit.rdoc", "doc/tutorials/html/creating.rdoc"]

    # Create a filelist containing all files starting with a dot and
    # ending in ".rdoc" under the "doc" directory.
    fl = Rant::FileList["doc/.*.rdoc"]
    fl.entries                      # => ["doc/.bar.rdoc"]

  Note::                The order of the file names in the filelist
                        and in the array returned by the +entries+
                        method is unspecified.

  Implementation Note:: Equivalent to
                        <code>Rant::FileList.new.hide_dotfiles.include(*patterns)</code>

* <b>Rant::FileList.glob(*patterns) { |filelist| ... }</b>

  The same as <tt>Rant::FileList[*patterns]</tt> but yields the
  new filelist to the block if a block is given. Additionally, it
  won't include the "." (current) and ".." (parent) directory entries.

  If a block is given, returns the return value of the block,
  otherwise the new filelist.

  Examples:

    require 'rant/filelist'

    Rant::FileList.glob("*.*) do |fl|
        fl.exclude "*.bak", "*~"
        fl.entries
    end                             # => ["README.txt", "setup.rb"]

    fl = Rant::FileList.glob(".*")
    fl.entries                      # => [".svn", ".README.txt.swp"]

    # compare the last example with the result of using
    # Rant::FileList[]:
    fl = Rant::FileList[".*"]
    fl.entries                      # => [".", "..", ".svn", ".README.txt.swp"]

  Implementation Note:: Before the given block is called, the filelist
                        is created and initialized with
                        <code>Rant::FileList.new.hide_dotfiles.ignore(".",
                        "..").include(*patterns)</code>

* <b>Rant::FileList.glob_all(*patterns) { |filelist| ... }</b>

  The same as <tt>Rant::FileList.glob(*patterns)</tt> but also
  includes files starting with a dot.

  Examples:

    require 'rant/filelist'

    Rant::FileList.glob_all("*.*) do |fl|
        fl.exclude "*.bak", "*~"
        fl.entries
    end                             # => ["README.txt", "setup.rb", ".README.txt.swp"]

  Implementation Note:: Before the given block is called, the filelist
                        is created and initialized with
                        <code>Rant::FileList.new.ignore(".",
                        "..").include(*patterns)</code>

* <b>Rant::FileList(arg)</b>

  Tries to convert +arg+ to an Rant::FileList object.
  
  If +arg+ responds to +to_rant_filelist+, the result of
  <tt>arg.to_rant_filelist</tt> is returned.
  
  If +arg+ responds to +to_ary+, a new filelist object containing the
  entries of <tt>arg.to_ary</tt> is returned.
  
  Note that changes to the returned filelist might cause changes to
  +arg+.

  Examples:

    require 'rant/filelist'

    fl = Rant::FileList.new
    Rant::FileList(fl)          # => fl

    # convert array to filelist
    a = ["foo", "bar"]
    fl = Rant::FileList(a)      # => new Rant::FileList
    fl.entries                  # => ["foo", "bar"]

    # obj doesn't respond to one of to_rant_filelist, to_ary
    obj = Object.new
    fl = Rant::FileList(obj)    # => raises TypeError

=== Rant::FileList instance methods

The <tt>Rant::FileList</tt> class includes the +Enumerable+ module.
Thus you can call all methods provided by the +Enumerable+ module on
+FileList+ instances. You can read the +ri+ documentation for those
methods:

    % ri Enumerable

Note that the methods +map+ (alias +collect+) and +select+ (alias
+find_all+) have slightly different semantics as documented by
+Enumerable+. Read below for documentation.

Most <tt>Rant::FileList</tt> instance methods are _lazy_. This means
that the actual work (e.g. glob pattern expansion) isn't done unless
the filelists entries are being read.

Following is a list of <tt>Rant::FileList</tt> instance methods. All
lazy methods are marked with <em>-lazy-</em>. All methods that force
evaluation of previously specified lazy operations, are marked with
<em>-eager-</em>. Note that not all methods marked with
<em>-eager-</em> are guaranteed to hold this predicate in future
versions. The <em>-eager-</em> marker is just intended as additional
information. To force execution of all previously lazy operations,
call the +resolve+ method.

    rb_names = Rant::FileList["**/*.rb"].map { |fn| File.basename(fn) }

    # force expansion of the glob pattern "**/*.rb" and execution of
    # the map operation
    rb_names.resolve

Note that you need to call +resolve+ only if the actual point in time
of execution is important, e.g. this could be if a map operation has
side effects like printing to standard output.

* <b>glob_unix(*patterns)</b>  <em>-lazy-</em>

  Include the file names specified by the glob patterns +patterns+.
  For exact glob pattern syntax read the section <em>Glob pattern
  syntax</em> below.

  Filenames starting with a dot ignored, unless explicitely matched
  by a pattern (e.g. ".*").

  Returns +self+.

  Examples:

    require 'rant/filelist'
    fl = Rant::FileList.new
    fl.include "**/*.{c,h}", "main.cpp"
    fl.entries                      # => ["lib/util.c", "include/util.h", "config.h", "main.cpp"]

  Note::    No specific order of entries included with this method is
            guaranteed.

* <b>glob_all(*patterns)</b>  <em>-lazy-</em>

  Same as <tt>glob_unix(*patterns)</tt> but no special handling of
  filenames starting with a dot.

  Examples:

    require 'rant/filelist'
    fl = Rant::FileList.new
    fl.include "**/*.{c,h}", "main.cpp"
    fl.entries                      # => ["lib/.util.c", "lib/util.c", "include/util.h", "config.h", "main.cpp"]

* <b>include(*patterns)</b>  <em>-lazy-</em>

  <b>glob(*patterns)</b>

  Include the file names specified by the glob patterns +patterns+.
  For exact glob pattern syntax read the section <em>Glob pattern
  syntax</em> below.

  Each filelist has a flag that indicates wheter a glob operation
  should hide dotfiles or not. It can be read with the method
  <tt>glob_dotfiles?</tt>, and set with the method
  <tt>glob_dotfiles=</tt> to either +true+ or +false+. For filelists
  created with <tt>Rant::FileList.new</tt> or
  <tt>Rant::FileList.glob_all()</tt> this flag is +true+ per default.
  For filelists created with <tt>Rant::FileList[]</tt> or
  <tt>Rant::FileList.glob()</tt> this flag is +false+ per default.
  If this flag is true, the +glob+ (alias +include+) method calls
  <tt>glob_all(*patterns)</tt>, otherwise it calls
  <tt>glob_unix(*patterns)</tt>.

  Returns +self+.

  Examples:

    require 'rant/filelist'
    fl = Rant::FileList.new
    fl.include "**/*.{c,h}", "main.cpp"
    fl.entries                      # => ["lib/.util.c", "lib/util.c", "include/util.h", "config.h", "main.cpp"]

    fl = Rant::FileList.new
    fl.glob_dotfiles = false
    fl.include "**/*.{c,h}", "main.cpp"
    fl.entries                      # => ["lib/util.c", "include/util.h", "config.h", "main.cpp"]

  Note::    No specific order of entries included with this method is
            guaranteed.

* <b>exclude(*patterns)</b>  <em>-lazy-</em>

  Remove all entries matching one of +patterns+. Each of +patterns+ is
  either a regular expression or a glob pattern as described under the
  section <em>Glob pattern syntax</em>, *except* that *currently* the
  characters <tt>{</tt> and <tt>}</tt> (curly braces) are not treated
  special.

  A call to +exclude+ does not effect entries added later to the
  filelist.

  Returns +self+.

  Examples:

    require 'rant/filelist'
    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "main.c~"]
    fl.exclude("*~")
    fl.entries                      # => ["main.c"]
    fl.include("*.h")
    fl.entries                      # => ["main.c", "main.h", "main.h~"]
    fl.exclude(/~$/)
    fl.entries                      # => ["main.c", "main.h"]

* <b>exclude_path(*patterns)</b>  <em>-lazy-</em>

  Like <tt>exclude(*patterns)</tt>, but doesn't accept regular
  expressions and the metacharacters in the patterns are treated more
  restrictive. Wildcards ("*") and "?" won't match filename
  separators.

  Returns +self+.

  Examples:

    # exclude vs. exclude_path
    fl1 = Rant::FileList["**/*.rb"]
    fl1.entries                     # => ["setup.rb", "lib/foo.rb"]

    fl2 = fl1.dup
    fl2.entries                     # => ["setup.rb", "lib/foo.rb"]

    fl1.exclude "*.rb"
    fl2.exclude_path "*.rb"

    fl1.entries                     # => []
    fl2.entries                     # => ["lib/foo.rb"]

    # another one
    fl = Rant::FileList(["a.rb", "lib/b.rb", "lib/foo/c.rb"])
    fl.exclude_path "lib/*.rb"
    fl.entries                      # => ["a.rb", "lib/foo/c.rb"]

  Note::                The method +exclude_path+ provides an
                        abstraction over the
                        <tt>File::FNM_PATHNAME</tt> flag for the
                        <tt>File.fnmatch</tt> method.

* <b>exclude_name(*names)</b>  <em>-lazy-</em>

  <b>shun(*names)</b>

  Remove all entries whose base name or one of its parent directory
  names is in +names+.

  A call to +exclude_name+ (or +shun+) does not effect entries added
  later to the filelist.

  Returns +self+.

  Examples:

    require 'rant/filelist'
    fl = Rant::FileList["**/*"]
    fl.entries                      # => ["CVS", "README", "README.CVS", "sub/CVS", "sub/README", "sub/CVS/foo", "sub/foo/bar"]
    fl.exclude_name("CVS")
    fl.entries                      # => ["README", "README.CVS", "sub/README", "sub/foo/bar"]

* <b>ignore(*patterns)</b>  <em>-lazy-</em>

  This filelist will never contain an entry matching one of
  +patterns+. Each element of +patterns+ is either a regular
  expression or a string. If the pattern is a string it matches all
  entries which have the string as base name or parent directory name
  (like +exclude_name+).

  This method applies to all previously added entries and to all
  entries that will be added in the future.

  Returns +self+.

  Examples:

    fl = Rant::FileList["**/*"]
    fl.entries                      # => ["CVS", "README", "README.CVS", "sub/CVS", "sub/README", "sub/CVS/foo", "sub/foo/bar"]

    fl.ignore("CVS")
    fl.entries                      # => ["README", "README.CVS", "sub/README", "sub/foo/bar"]

    fl.concat("dir/CVS", "dir")
    # note that fl doesn't contain "dir/CVS"
    fl.entries                      # => ["README", "README.CVS", "sub/README", "sub/foo/bar", "dir"]

* <b>files</b>  <em>-lazy-</em>

  Get a new filelist containing only the existing files from +self+.

  Examples:

    fl = Rant::FileList["**/*"]
    fl.concat ["does_not_exist"]
    fl.entries                      # => ["README", "sub", "sub/README", "does_not_exist"]

    files = fl.files
    files.entries                    # => ["README", "sub/README"]

  Rantfile Note::
            In Rantfiles, this method is not loaded per default. You
            have to <code>import "filelist/std"</code> first.

* <b>dirs</b>  <em>-lazy-</em>

  Get a new filelist containing only the existing directories from
  +self+.

  Examples:

    fl = Rant::FileList["**/*"]
    fl.concat ["does_not_exist"]
    fl.entries                      # => ["README", "sub", "sub/README", "does_not_exist"]

    dirs = fl.dirs
    dirs.entries                    # => ["sub"]

  Rantfile Note::
            In Rantfiles, this method is not loaded per default. You
            have to <code>import "filelist/std"</code> first.

* <b>no_dir</b>  <em>-lazy-</em>

  Remove all existing directories.

  A call to +no_dir+ does not effect entries added later to the
  filelist.

  Returns +self+.

  Examples:

    require 'rant/filelist'
    # create a filelist including all files in the current directory
    # and its subdirectories (recursive).
    fl = Rant::FileList["**/*"]
    fl.entries                    => ["README", "lib", "bin", "bin/rant", "lib/rant.rb"]
    fl.no_dir
    # now fl doesn't contain directory entries
    fl.entries                    => ["README", "bin/rant", "lib/rant.rb"]

  Rantfile Note::
            In Rantfiles, this method is not loaded per default. You
            have to <code>import "filelist/std"</code> first.

* <b>no_dir(dir)</b>  <em>-lazy-</em>

  Remove all entries with a parent directory with the name +dir+ and
  all directories with a base name of +dir+.

  A call to this method does not effect entries added later to the
  filelist.

  Returns +self+.

  Examples:

    fl = Rant::FileList["**/*"]
    fl.entries                      # => ["README", "coverage", "coverage/index.html", "bin/coverage", "test/coverage", "test/coverage/index.html", "test/test_foo.rb"]
    fl.no_dir("coverage")
    # assumin "bin/coverage" is not a directory
    fl.entries                      # => ["README", "bin/coverage", "test/test_foo.rb"]

  Rantfile Note::
            In Rantfiles, this method is not loaded per default. You
            have to <code>import "filelist/std"</code> first.

* <b>select { |fn| ... }</b>  <em>-lazy-</em>

  <b>find_all { |fn| ... }</b>

  Returns a copy of this filelist which contains only the elements for
  which the given block returns true. The calling filelist object
  isn't modified.

  Examples:

    # create a list of all files in the current directory and its
    # subdirectories
    all_files = Rant::FileList["**/*"].no_dir

    # create a list which contains the file names of all empty files
    empty_files = all_files.select { |fn| File.size(fn) == 0 }

    puts "The following files are empty:"
    # print the file names, one per line
    puts empty_files

* <b>map { |fn| ... }</b>  <em>-lazy-</em>

  <b>collect { |fn| ... }</b>

  Each entry of this filelist is passed in turn to the given block.
  The method returns a copy of this filelist with all entries replaced
  by the return value of block execution.

  The calling filelist object is not modified.

  Examples:

    names = Rant::FileList["**/*"]

    # create a filelist containing only absolute pathes
    abs_pathes = names.map { |fn| File.expand_path(fn) }

* <b>ext(ext_str)</b>  <em>-lazy-</em>

  Returns a new filelist containing the same entries as this list, but
  all entries have the extension +ext_str+.

  The calling filelist object is not modified.

  Examples:

    c_files = Rant::FileList["*.c"]
    c_files.entries                 # => ["a.c", "b.c"]
    obj_files = c_files.ext("o")
    obj_files.entries               # => ["a.o", "b.o"]

    files = Rant::FileList(["a.c", "b", "c.en.doc", "d.txt"])
    txt_files = file.ext("txt")
    txt_files.entries               # => ["a.txt", "b.txt", "c.en.txt", "d.txt"]

* <b>uniq!</b>  <em>-lazy-</em>

  Removes duplicate entries.

  Returns +self+.

  Examples:

    files = Rant::FileList(["a", "b", "a", "a"])
    files.uniq!
    files.entries                   # => ["a", "b"]

* <b>sort!</b>  <em>-lazy-</em>

  Sort the entries in this list in alphabetical order.

  Returns +self+.

  Examples:

    fl = Rant::FileList(["b", "a", "c"])
    fl.sort!
    fl.entries                      # => ["a", "b", "c"]

* <b>map! { |fn| ... }</b>  <em>-lazy-</em>

  Pass each entry to the given block and replace it by the return
  value of the block.

  Returns +self+.

  Examples:

    # get a list of directories containing C source files
    src_dirs =
        Rant::FileList.glob "**/*.{c,h}" do |fl|
            fl.map! { |fn| File.dirname(fn) }
            fl.uniq!
        end

* <b>reject! { |fn| ... }</b>  <em>-lazy-</em>

  Pass each entry to the given block and remove those entries for
  which the block returns a true value.

  Returns +self+.

  Examples:

    non_empty_files = Rant::FileList["**/*"].reject! { |fn|
        stat = File.stat(fn)
        !stat.file? or stat.zero?
    }

* <b>resolve</b>  <em>-eager-</em>

  Execute all lazy operations.

  Returns +self+.

* <b>to_s</b>  <em>-eager-</em>

  Joins all entries with a single space as separator. Spaces in
  entries are escaped for the shell used on the current platform.

  Examples:

    txt_files = Rant::FileList["*.txt"]
    txt_files.entries                # => ["User Manual.txt", "README.txt"]
    txt_files.to_s
        # on windows: '"User Manual.txt" README.txt'
        # unix/linux: 'User\ Manual.txt README.txt'

    # start the vim editor to edit all text files
    system "vim #{txt_files}"
    
  Note::    Might escape more special shell characters in the future.

* <b>entries</b>  <em>-eager-</em>

  <b>to_a</b>
  
  <b>to_ary</b>

  Convert this filelist to an array.

  Examples:

    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "util.c"]

  Especially the definition of the +to_ary+ method has much impact on
  how a filelist object is treated by Ruby libraries. Per convention,
  an object that responds to +to_ary+ can be passed to most methods
  that expect an actual array. So, in most cases you can use a
  filelist object where an array is expected.

  Examples:

    a = ["foo", "bar"]
    a.concat Rant::FileList["*.c"]
    a                               # => ["foo", "bar", "main.c", "util.c"]

    # remove all object files
    require 'fileutils'
    FileUtils.rm_f Rant::FileList["**/*.o"]

    # flattening an array (a somewhat artifical example ;)
    a = ["foo"]
    a << Rant::FileList["*.c"].ext("o")
    a.flatten                       # => ["foo", "main.o", "util.o"]

  It is not guaranteed that this method always returns the same
  object. It is guaranteed that the returned object is an instance of
  the +Array+ class. Note that changes to the returned array might
  affect the filelist and cause an undefined filelist state.

* <b>+(other)</b>  <em>-lazy-</em>

  Returns a new filelist containing the entries of +self+ and +other+.
  +other+ has to respond to +to_rant_filelist+ or to +to_ary+,
  otherwise a +TypeError+ is risen.

  Examples:

    c_files = Rant::FileList["*.c"]
    h_files = Rant::FileList["*.h"]
    src_files = c_files + h_files

    c_files.entries                 # => ["main.c", "util.c"]
    h_files.entries                 # => ["main.h", "util.h"]
    src_files.entries               # => ["main.c", "util.c", "main.h", "util.h"]

* <b>size</b>  <em>-eager-</em>

  Returns the number of entries in this filelist.

  Examples:

    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "util.c"]
    fl.size                         # => 2

* <b>empty?</b>  <em>-eager-</em>

  Returns true if this filelist doesn't contain any entry.

  Examples:

    fl = Rant::FileList([])
    fl.empty?                       # => true

    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "util.c"]
    fl.empty?                       # => false

* <b>join(sep = ' ')</b>  <em>-eager-</em>

  Join the entries together to form a single string. Entries are
  seperated with the given separator string +sep+ or a single space if
  +sep+ is not given.

  Examples:

    fl = Rant::FileList(["a", "b"])
    fl.join                         # => "a b"
    fl.join("\n")                   # => "a\nb"

* <b>pop</b>  <em>-eager-</em>

  Removes the last element and returns it, or +nil+ if this filelist
  is empty.

  Examples:

    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "util.c"]
    fl.pop                          # => "util.c"
    fl.entries                      # => ["main.c"]

* <b>push(entry)</b>  <em>-eager-</em>

  Append +entry+ to this filelist.

  Returns +self+.

  Examples:

    fl = Rant::FileList["*.c"]
    fl.push("foo")
    fl.entries                      # => ["main.c", "util.c", "foo"]

* <b>shift</b>  <em>-eager-</em>

  Removes the first entry and returns it. Returns +nil+ if the
  filelist is empty.

  Examples:

    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "util.c"]
    fl.shift                        # => "main.c"
    fl.entries                      # => ["util.c"]

* <b>unshift(entry)</b>  <em>-eager-</em>

  Insert +entry+ at the first position.

  Returns +self+.

  Examples:

    fl = Rant::FileList["*.c"]
    fl.entries                      # => ["main.c", "util.c"]
    fl.unshift("foo")
    fl.entries                      # => ["foo", "main.c", "util.c"]

* <b>keep(entry)</b>

  Add +entry+ to this filelist. +entry+ will stay in this list, even
  if it matches a pattern given to +exclude+ or +ignore+. The position
  of +entry+ in this list is unspecified.

  Examples:

    fl = Rant::FileList.new
    fl.include "README.txt", "README.txt~"
    fl.keep "NEWS.txt"
    fl.keep "NEWS.txt~"
    fl.exclude "*~"
    fl.uniq!
    # Note that "README.txt~" was excluded, but "NEWS.txt~" not.
    fl.entries                      # => ["README.txt", "NEWS.txt", "NEWS.txt~"]

* <b>concat(ary)</b>

  +ary+ has to respond to +to_ary+ (+ary+ could be an Array or other
  filelist). Appends the entries of +ary+ to this filelist.

  Returns +self+.

  Examples:

    fl = Rant::FileList(["a"])
    fl.concat ["b", "c"]
    fl.entries                      # => ["a", "b", "c"]

    fl = Rant::FileList.new
    fl.include "*.c"
    fl.concat ["foo", "bar"]
    fl.entries                      # => ["main.c", "util.c", "foo", "bar"]
    
* <b>each { |entry| ... }</b>

  Iterate over the filelist entries.

  Examples:

    # cat.rb - A simple cat program using Ruby glob patterns.
    require 'rant/filelist'
    Rant::FileList[*ARGV].no_dir.each { |file| print File.read(file) }

    # example usage: print contents of all Ruby files under lib
    % cat.rb "lib/**/*.rb"

* <b>to_rant_filelist</b>

  Returns +self+.

* <b>dup</b>

  Returns a copy of +self+. Thus after calling this method, there are
  two equal filelist objects. It is guaranteed that modifications of
  one filelist do not affect the other filelist, as long as the entry
  strings aren't modified.

  Examples:

    a = Rant::FileList["*.c"]
    a.entries                       # => ["main.c", "util.c"]

    b = a.dup
    b.entries                       # => ["main.c", "util.c"]

    a.include("*.h")
    a.entries                       # => ["main.c", "util.c", "main.h", "util.h"]
    # b not affected
    b.entries                       # => ["main.c", "util.c"]

    # Note: the original entry strings aren't modified.
    # a not affected
    b.map! { |entry| entry.capitalize }
    b.entries                       # => ["Main.c", "Util.c"]
    a.entries                       # => ["main.c", "util.c", "main.h", "util.h"]

    c = a.dup
    # DON'T DO THAT. Look at the previous example on how to accomplish
    # the same.
    c.each { |entry| entry.capitalize! }
    c.entries                       # => ["Main.c", "Util.c", "Main.h", "Util.h"]
    # Now the state of a is unspecified: The individual entries may be
    # capitalized or not!

* <b>copy</b>

  Returns a deep copy of +self+. Thus after calling this method, there
  are two equal filelist objects. It is guaranteed that modification
  of one filelist (or its entries) has no impact on the other
  filelist.

  Examples:

    a = Rant::FileList["*.c"]
    a.entries                       # => ["main.c", "util.c"]

    b = a.copy
    b.entries                       # => ["main.c", "util.c"]

    b.each { |entry| entry.capitalize! }
    b.entries                       # => ["Main.c", "Util.c"]

    a.entries                       # => ["main.c", "util.c"]

* <b>glob_dotfiles</b>

  Convinience method for <code>glob_dotfiles = true</code>. The
  following calls to +glob+ (alias +include+) won't treat filenames
  starting with a dot special.

  Returns +self+.

* <b>hide_dotfiles</b>

  Convinience method for <code>glob_dotfiles = false</code>. The
  following calls to +glob+ (alias +include+) won't include filenames
  starting with a dot.

  Returns +self+.

* <b>inspect</b>

  Overrides <tt>Object#inspect</tt>. Defined mainly for use in +irb+.
  The +inspect+ method as defined by the +Object+ class is still
  available under the name +object_inspect+.

  Examples:

    # irb session
    # Remember that irb uses the inspect method to show results (lines
    # starting with `=>').

    % irb
    irb(main):001:0> require 'rant/filelist'
    => true
    irb(main):002:0> fl = Rant::FileList["*.rb"]
    => #<Rant::FileList:0x402e46e0 glob:unix res:1 entries:0>
    irb(main):003:0> fl.resolve
    => #<Rant::FileList:0x402e46e0 glob:unix entries:2["install.rb", "setup.rb"]>
    irb(main):004:0>

  Note::
    Don't rely on the exact format of the string produced by
    +inspect+.
  Rantfile Note::
    To get this +inspect+ method in Rantfiles, you have to
    <code>import "filelist/std"</code> first.

* <b>object_inspect</b>

  Ruby's default +inspect+ method.

=== Glob pattern syntax

The syntax used for filelist glob patterns is the same as for the
<tt>Dir.glob</tt> Ruby core method.

Basically, a glob pattern is a string where a few characters are
treated special. Unless otherwise mentioned, a pattern is matched
against the file/directory entries in the current directory. The
following is a list of characters (the so called "metacharacters")
that get special treatment:

(Parts of this documentation are taken from the output of <tt>% ri
Dir.glob</tt>, Ruby 1.8.4).

<tt>*</tt>::    Match any file/directory. Can be restricted, e.g.
                "*.txt" matches all files/directories ending in
                ".txt". The pattern "\*a\*" matches any entry
                containing the character "a". The pattern "bar*"
                matches any entry starting with "bar". The pattern
                "lib/*.rb" matches any entry under the "lib" directory
                that ends in ".rb".

<tt>**</tt>::   Matches directories recursively. E.g. the pattern
                "**/*.rb" matches all entries in the current directory
                and all its subdirectories (recursively) that end in
                ".rb".

<tt>?</tt>::    Matches any one character.

<tt>[set]</tt>:: Matches any one character in +set+. E.g. the pattern
                 "ca[rt]s" matches the entries "cars" and "cats".

<tt>{p,q}</tt>:: Matches either literal +p+ or literal +q+.
                 Matching literals may be more than one character in
                 length. More than two literals may be specified.

<tt>\\</tt>::   Escapes the following metacharacter. E.g. while
                pattern "a*b" would match any entry starting with "a"
                and ending with "b", the pattern "a\\*b" literally
                matches the entry "a*b".

Some Ruby programmers use the <tt>File.join(dir, filename)</tt> method
to construct patterns for <tt>Dir.glob</tt> (or <tt>Dir[]</tt>). The
<tt>Rant::FileList</tt> class guarantees support for either directly
using a slash ("/") as filename separator, which is recommended, or
using <tt>File.join</tt>.

Examples:

    # Using a slash as filename separator, supported and preferred
    fl = Rant::FileList["lib/*.c"]

    # Using File.join, supported
    pattern = File.join("lib", "*.c")
    fl = Rant::FileList[pattern]

Note that the Rant::FileList class only supports a slash as filename
separator. To convert a filename into Rant's internal filename format,
use the <tt>Rant::Sys.regular_filename</tt> method.

Example script, filename.rb:

    require 'rant/filelist'

    print "Rant internal filename: "
    puts Rant::Sys.regular_filename(ARGV[0])

Executing this on windows:

    % ruby filename.rb foo\bar
    Rant internal filename: foo/bar

== See also

Rant Overview::
    README[link:files/README.html]
Using filelists in Rantfiles::
    doc/sys_filelist.rdoc[link:files/doc/sys_filelist_rdoc.html]
Rant libraries::
    doc/rubylib.rdoc[link:files/doc/rubylib_rdoc.html]
Rantfile basics::
    doc/rantfile.rdoc[link:files/doc/rantfile_rdoc.html]
