doc/ANNOUNCE in rio-0.3.3 vs doc/ANNOUNCE in rio-0.3.4
- old
+ new
@@ -1,104 +1,193 @@
-For your perusal -- Rio 0.3.2
+New and Improved -- Rio 0.3.4
== Overview
Rio is a Ruby I/O convenience class wrapping much of the functionality
-of IO, File and Dir. Rio also uses Pathname, FileUtils, Tempfile,
-StringIO, OpenURI, Zlib, and CSV to provide similar functionality using
-a simple consistent interface. In addition to forwarding the interfaces
-provided by IO, File, and Dir to an appropriate object, Rio provides
-a "grande" interface that allows many common application-level I/O and
+of IO, File and Dir. Rio also uses FileUtils, Tempfile, StringIO,
+OpenURI, Zlib, and CSV to provide similar functionality using a simple
+consistent interface. In addition to forwarding the interfaces
+provided by IO, File, and Dir to an appropriate object, Rio provides a
+"grande" interface that allows many common application-level I/O and
file-system tasks to be expressed succinctly.
-== New for version 0.3.3
-* Expanded support and documentation for CSV files
- Examples:
- * Copy, changing the separator to a semicolon
- rio('comma.csv').csv > rio('semicolon.csv').csv(';')
- * Iterate through a file with each line parsed into an array
- rio('afile.csv').csv { |array_of_fields| ...}
- * Create an array of arrays of selected fields
- array_of_arrays = rio('afile.csv').csv.columns(1..3,7).to_a
- * Create a tab separated file of accounts in a UNIX passwd file,
- listing only the username, uid, and realname fields
- rio('/etc/passwd').csv(':').columns(0,2,4) > rio('report).csv("\t")
+== SYNOPSIS
-Project:: http://rubyforge.org/projects/rio/
-Documentation:: http://rio.rubyforge.org/
-Bugs:: http://rubyforge.org/tracker/?group_id=821
+For the following assume:
+ astring = ""
+ anarray = []
-
-== New for version 0.3.2
+Copy or append a file to a string
+ rio('afile') > astring # copy
+ rio('afile') >> astring # append
-* Based on a suggestion by Wybo Decker and code attributed to Nobu Nokada,
- Rio now supports temporary directories in addition to temporary files.
-* Bug fixes
-* More tests and documentation.
+Copy or append a string to a file
+ rio('afile') < astring # copy
+ rio('afile') << astring # append
+Copy or append the lines of a file to an array
+ rio('afile') > anarray
+ rio('afile') >> anarray
+
+Copy or append a file to another file
+ rio('afile') > rio('another_file')
+ rio('afile') >> rio('another_file')
-== Version 0.3.1
+Copy a file to a directory
+ rio('adir') << rio('afile')
-A Rio is and can manipulate:
-* a path
-* the string representing that path
-* the file, directory, web-page, or IO object to which that path refers
-* the object created by opening that file or directory.
+Copy a directory structure to another directory
+ rio('adir') >> rio('another_directory')
-A Rio open itself, closes itself and selects its mode based on how it
-used and the object referenced.
+Copy a web-page to a file
+ rio('http://rubydoc.org/') > rio('afile')
-== Grande interface
+Ways to get the chomped lines of a file into an array
+ anarray = rio('afile').chomp[] # subscript operator
+ rio('afile').chomp > anarray # copy-to operator
+ anarray = rio('afile').chomp.to_a # to_a
+ anarray = rio('afile').chomp.readlines # IO#readlines
+
+Copy a gzipped file un-gzipping it
+ rio('afile.gz').gzip > rio('afile')
-With the grande interface you can:
+Copy a plain file, gzipping it
+ rio('afile.gz').gzip < rio('afile')
-Copy...
- rio('afile') > astring # a file into a string
- rio('afile') < astring # a string into a file
- rio('afile') > anarray # lines of a file into array
- rio('afile') < anarray # an array into a file
- rio('afile') > rio('another_file') # a file into another file
- rio('adir') > rio('another_directory') # a directory into another
- rio('http://rubydoc.org/') > rio('afile') # a web page into a file
+Copy a file from a ftp server into a local file un-gzipping it
+ rio('ftp://host/afile.gz').gzip > rio('afile')
-Iterate...
- rio('adir').entries { |entrio| ... } # over directory entries
- rio('adir').files { |entrio| ... } # over only files
- rio('adir').dirs { |entrio| ... } # over only directories
- rio('afile').lines { |line| ... } # over lines in a file
+Iterate over the entries in a directory
+ rio('adir').entries { |entrio| ... }
-Create an array...
- rio('adir').files[] # of files
- rio('adir').dirs[] # of directories
- rio('afile').lines[] # of lines
+Iterate over only the files in a directory
+ rio('adir').files { |entrio| ... }
-Whether copying, iterating or returning an array
-Rio provides common input manipulations
+Iterate over only the .rb files in a directory
+ rio('adir').files('*.rb') { |entrio| ... }
- rio('afile').chomp > anarray # chomped lines to an array
- anarray = rio('afile').chomp[] # same thing
- rio('afile.gz').gzip > rio('afile') # ungzip a file
- rio('afile.gz').gzip < rio('afile') # gzip a file
- rio('afile.gz').chomp { |line| ...} # iterate chomped lines
+Iterate over .rb files but not symlinks to .rb files
+ rio('adir').files('*.rb').skip(:symlink?) { |entrio| ... }
-Whether copying, iterating or returning an array
-Rio provides simple input selection
+Iterate over only the _dot_ files in a directory
+ rio('adir').files(/^\./) { |entrio| ... }
- rio('afile').lines(0..9) > rio('file2') # the first 10 lines
- rio('afile').lines(/Rio/) { |line| ...} # lines containing 'Rio'
- anarray = rio('adir').files['*.rb'] # ruby files
+Iterate over the files in a directory and its subdirectories, skipping
+'.svn' and 'CVS' directories
-Manipulation and selection methods can be combined
+ rio('adir').norecurse(/^\.svn$/,'CVS').files { |entrio| ... }
- rio('afile').gzip.lines(/Rio/) > astring # 'Rio' lines from gz file
- anarray = rio('afile').chomp[0..9] # first 10 lines chomped
+Create an array of the .rb entries in a directory
+ anarray = rio('adir')['*.rb']
-Many more examples and documentation at http://rio.rubyforge.org/
+Create an array of the .rb entries in a directory and its
+subdirectories.
+ anarray = rio('adir').all['*.rb']
+Iterate over the .rb files in a directory and its subdirectories
+ rio('adir').all.files('*.rb') { |entrio| ... }
+
+Iterate over the non-empty, non-comment chomped lines of a file
+ rio('afile').chomp.skip.lines(:empty?,/^\s*#/) { |line| ... }
+
+Copy the output of th ps command into an array, skipping the header
+line and the ps command entry
+ rio(?-,'ps -a').skip.lines(0,/ps$/) > anarray
+
+Prompt for input and return what was typed
+ ans = rio(?-).print("Type Something: ").chomp.gets
+
+Change the extension of all .htm files in a directory and its
+subdirectories to .html
+ rio('adir').rename.all.files('*.htm') do |htmfile|
+ htmfile.extname = '.html'
+ end
+
+Create a symbolic link 'asymlink' in 'adir' which refers to
+'adir/afile'
+ rio('adir/afile').symlink('adir/asymlink')
+
+Copy a CSV file, changing the separator to a semicolon
+ rio('comma.csv').csv > rio('semicolon.csv').csv(';')
+
+Iterate through a CSVfile with each line parsed into an array
+ rio('afile.csv').csv { |array_of_fields| ...}
+
+Create a tab separated file of accounts in a UNIX passwd file,
+listing only the username, uid, and realname fields
+ rio('/etc/passwd').csv(':').columns(0,2,4) > rio('rpt').csv("\t")
+
+== New for version 0.3.4
+
+* New Grande Selection parameter.
+
+ A major weakness of Rio's selection methods (lines, files, etc.)
+ has always been that it only implemented a logical OR.
+
+ rio('afile').lines(0..10,/Rio/) {...}
+ iterates through lines that are in the range 0..10 OR
+ contain 'Rio'.
+
+ rio('adir').files(:executable?,'*.rb') {...}
+ iterates through files that are executable OR match '*.rb'
+
+ Selecting files that matched both required using a proc.
+ rio('adir').files(proc{ |f| f.executable? and f.fnmatch?('*.rb')}) {...}
+
+ Rio's grande selection methods will now accept an array of conditions
+ which must all be matched, in order to be selected. A logical AND.
+
+ rio('adir').files([:executable?,'*.rb']) {...}
+
+ The array, of course, need not be the only paramter.
+
+ rio('adir').files('*.exe',[:executable?,'*.rb']) {...}
+
+ selects .exe files and .rb files that are executable.
+
+* Renamed some of grande rejection methods.
+ (based on a suggestion by Gavin Sinclair)
+ nolines => skiplines
+ nofiles => skipfiles
+ etc.
+
+* New skip() grande method
+ rio('afile').skip.lines(/Rio/) # same as skiplines(/Rio/)
+ rio('afile').lines(/Rio/).skip(0..9) # lines with 'Rio', exclude
+ # the first ten lines
+
+* Alternative syntaxes for creating Rios that have no path.
+ rio(?-) # create a Rio refering to stdio
+ rio(:stdio) # same thing.
+ rio.stdio # same thing
+ RIO.stdio # ditto
+ RIO::Rio.stdio # once again
+
+* From Pathname added
+ * root?
+ * mountpoint?
+ * realpath
+ * cleanpath
+
+* Removed Rio#slurp in favor of Rio#contents.
+
+* Added aliases for the copy operators. (suggested by Dave Burt)
+ * copy_to >
+ * append_to >>
+ * copy_from <
+ * append_from <<
+
+* Bug fixes and corrections
+
+Project:: http://rubyforge.org/projects/rio/
+Documentation:: http://rio.rubyforge.org/
+Bugs:: http://rubyforge.org/tracker/?group_id=821
+Email:: rio4ruby@rubyforge.org
+
== Copyright
Copyright (c) 2005, Christopher Kleckner. All rights reserved
== License
Rio is released under the GNU General Public License
(http://www.gnu.org/licenses/gpl.html)
--Christopher Kleckner
\ No newline at end of file
+-Christopher Kleckner