Module: RIO::Doc::HOWTO

Defined in:
lib/rio/doc/HOWTO.rb

Overview

Rio - Ruby I/O Comfort Class

Rio is a convenience class wrapping much of the functionality of IO, File, Dir, Pathname, FileUtils, Tempfile, StringIO, OpenURI, Zlib, and CSV.

HOWTO…

Read a single file

ario = rio('afile')
string = ""
array = []
  • Read a file into a string.

    # method 1
    string = ario.contents
    # method 2
    ario > string
    
  • Append a file onto a string.

    # method 1
    ario >> string
    # method 2
    string += ario.contents
    
  • Read lines of a file into an array

    # method 1
    array = ario[]
    # method 2
    ario > array
    # method 3
    array = ario.to_a
    # method 4 
    array = ario.readlines
    
  • Append lines of a file into an array

    # method 1
    ario >> array
    # method 2
    array += ario.lines[]
    
  • Read the first 10 lines of a file into an array

    # method 1
    array = ario[0...10]
    # method 2
    array = ario.lines[0...10]
    # method 3
    ario.lines(0...10) > array
    
  • Read lines of a file into an array, with each line chomped

    # method 1
    array = ario.chomp[]
    # method 2
    array = ario.chomp.lines[]
    # method 3
    ario.chomp > array
    
  • Append the first 10 lines of a file into an array, with each line chomped

    # method 1
    array += ario.chomp.lines[0...10]
    # method 2
    ario.chomp.lines(0...10) >> array
    
  • Read all lines starting with ‘require’ into an array, with each line chomped

    # method 1
    array = ario.chomp.lines[/^\s*require/]
    # method 2
    ario.chomp.lines(/^\s*require/) > array
    
  • Read a gzipped file into a string

    # method 1
    rio('afile.gz').gzip > string
    # method 2
    string = rio('afile.gz').gzip.contents
    
  • Append a gzipped file into a string

    # method 1
    rio('afile.gz').gzip >> string
    # method 2
    string += rio('afile.gz').gzip.contents
    
  • Iterate through all the lines of a file

    # method 1
    rio('afile').lines { |line| ... }
    # method 2
    rio('afile').each { |line| ... }
    # method 3
    rio('afile').each_line { |line| ... }
    
  • Iterate through the lines of a gzipped file

    rio('afile.gz').gzip { |line| ... }
    
  • Iterate through all non-empty lines of a gzipped file, with each line chomped

    rio('afile.gz').gzip.chomp.skiplines(:empty?) { |line| ... }
    
  • Iterate through the first 100 lines of a file

    # method 1
    rio('afile').lines(0...100) { |line| ... }
    
  • Iterate through the first line and all ruby comment lines in a gzipped file

    rio('afile.rb.gz').gzip.lines(0,/^\s*#/) { |line| ... }
    
  • Iterate through the lines of a ruby file that are neither empty nor comments, with all lines chomped

    rio('afile.rb.gz').chomp.skiplines(/^\s*#/,:empty?) { |line| ... }
    
  • Read all the comment lines from a ruby file into an array with all lines chomped

    # method 1
    array = rio('afile.rb').chomp.lines[/^\s*#/]
    # method 2
    rio('afile.rb').chomp.lines(/^\s*#/) > array
    
  • Read lines of a file into an array, with each line chomped, skipping any lines longer than 1024 chars

    # method 1
    ario.chomp.lines(proc{ |line| line.length <= 1024}) > array
    # method 2
    array = ario.chomp.skiplines[proc{ |line| line.length > 1024}]
    # method 3
    array = ario.chomp.lines(proc{ |line| line.length <= 1024}).to_a
    

Write to a single file

ario = rio('afile')
string = "A String\n"
array = ["Line 0\n","Line 1\n"]
  • Write a string to a file, leaving the Rio open

    # method 1
    ario.puts(string)
    # method 2
    ario.print(string)
    # method 3
    ario.noautoclose < string
    
  • Write a string to a file and close the file

    # method 1
    rio('afile') < string
    # method 2
    ario.print!(string)
    # method 3
    ario.print(string).close
    
  • Append a string to a file, leaving the Rio open

    # method 1
    ario.a.puts(string)
    # method 2
    ario.a.print(string)
    # method 3
    ario.noautoclose << string
    
  • Append a string to a file and close the file

    # method 1
    rio('afile') << string
    # method 2
    rio('afile').a.print!(string)
    # method 3
    rio('afile').a.print(string).close
    
  • Write an array to a file, leaving the Rio open

    # method 1
    ario = rio('afile').nocloseoncopy
    ario << array
    # method 2
    ario.noautoclose < array
    
  • Write an array to a file and close the file

    # method 1
    rio('afile') < array
    

Select records

ario = rio('afile')
string = ""
array = []
  • Put lines one thru ten and line 100 into an array

    # method 1
    array = ario[0..9,99]
    # method 2
    array = ario[0...10,99..99]
    # method 3
    ario(0..9,99) > array
    
  • Put lines one thru ten,line 100 and lines starting with ‘zippy’ into an array

    # method 1
    array = ario[0..9,99,/^zippy/]
    # method 2
    array = ario[0...10,99..99,/^zippy/]
    # method 3
    ario(0..9,99,/^zippy/) > array
    
  • Put lines that are longer than 128 bytes into an array

    # method 1
    array = ario[proc{ |l| l.length > 128}]
    # method 2
    array = ario.lines[proc{ |l| l.length > 128}]
    # method 3
    array = ario.skiplines[proc{ |l| l.length <= 128}]
    
  • Copy all lines that do not start with ‘zippy’ into another file

    # method 1
    ario.skiplines(/^zippy/) > rio('another_file')
    # method 2
    ario.lines.skiplines(/^zippy/) > rio('another_file')
    # method 3
    rio('another_file') < ario.skiplines(/^zippy/)
    
  • Copy the first 10 lines and lines starting with ‘zippy’, but exclude any lines longer than 128 bytes

    # method 1
    ario.lines(0...10,/^zippy/).skiplines(proc{ |l| l.length > 128}] > rio('another_file')
    # method 2
    rio('another_file') < ario.lines(0...10,/^zippy/).skiplines(proc{ |l| l.length > 128})
    

Select directory entries

ario = rio('adir')
string = ""
array = []
  • Put all entries with the extension ‘.txt’ into an array

    # method 1
    array = ario['*.txt']
    # method 2
    array = ario[/\.txt$/]
    # method 3
    array = ario.entries['*.txt']
    
  • Put all files with the extension ‘.txt’ into an array

    # method 1
    array = ario.files['*.txt']
    # method 2
    array = ario.files[/\.txt$/]
    # method 3
    array = ario.files['*.txt']
    
  • Put all entries with the extension ‘.txt’ into an array, including those in subdirectories

    # method 1
    array = ario.all['*.txt']
    # method 2
    array = ario.all[/\.txt$/]
    # method 3
    array = ario.all.entries['*.txt']
    
  • Put all entries with the extension ‘.txt’ into an array, including those in subdirectories, except those in subdirectories name ‘.svn’

    # method 1
    array = ario.norecurse('.svn').all['*.txt']
    # method 2
    array = ario.norecurse(/^\.svn$/).all[/\.txt$/]
    # method 3
    array = ario.norecurse('.svn').entries['*.txt']
    # method 4
    array = ario.entries('*.txt').norecurse('.svn').to_a
    # method 5
    array = ario.norecurse('.svn')['*.txt']
    
  • Put all directories (recursively) into an array

    # method 1
    array = ario.dirs[]
    # method 2
    array = ario.dirs.to_a
    
  • Put all entries (recursively) into an array, but limit the depth of recursion to 2

    # method 1
    array = ario.norecurse(3).to_a
    
  • Iterate through ruby files in a directory and subdirectories skipping those in the ‘.svn’, and ‘pkg’ directories

    # method 1
    is_ruby_exe = proc{ |f| f.executable? and f[0][0] =~ /^#!.+ruby/ }
    ario.norecurse('.svn','pkg').files('*.rb',is_ruby_exe) { |f| ... }
    # method 2
    is_ruby_exe = proc{ |f| f.executable? and f.gets =~ /^#!.+ruby/ }
    ario.norecurse('.svn','pkg').files('*.rb',is_ruby_exe) { |f| ... }
    
  • Put all files excluding those that are symlinks to files in an array

    # method 1
    array = ario.skipfiles[:symlink?]
    # method 2
    array = ario.skipfiles(:symlink?).files[]
    # method 3
    array = ario.skipfiles(:symlink?).to_a
    # method 4
    array = ario.files.skipfiles[:symlink?]
    
  • Put all entries that are not files (or symlinks to files) into an array

    # method 1
    array = ario.skipfiles[]
    # method 2
    array = ario.skipfiles.to_a
    
  • Put all entries that are symlinks to files into an array

    # method 1
    array = ario.files[proc{|f| f.file? and f.symlink?}]
    # method 2
    array = ario.files(proc{|f| f.file? and f.symlink?}).to_a
    
  • Put all directories except those named ‘.svn’ into an array

    # method 1
    array = ario.skipdirs['.svn']
    # method 2
    array = ario.skipdirs[/^\.svn$/]
    # method 3
    array = ario.skipdirs('.svn').to_a
    # method 4
    array = ario.skipdirs('.svn').dirs[]
    # method 5
    array = ario.skipdirs('.svn')[]
    

Read and writing files

ario = rio('afile')
string = ""
array = []
  • Copy the contents of one file into another file

    # method 1
    rio('srcfile') > rio('dstfile')
    # method 2
    rio('dstfile') < rio('srcfile')
    # method 3
    rip('dstfile').print!(rio('srcfile').contents)
    
  • Append the contents of one file to another file

    # method 1
    rio('srcfile') >> rio('dstfile')
    # method 2
    rio('dstfile') << rio('srcfile')
    # method 3
    rip('dstfile').a.print!(rio('srcfile').contents)
    
  • Copy the first 10 lines of one file to another file

    # method 1
    rio('srcfile').lines(0...10) > rio('dstfile')
    # method 2
    rio('dstfile') < rio('srcfile').lines(0...10)
    # method 3
    rio('dstfile') < rio('srcfile').lines[0...10]
    
  • Concatenate several files into one

    # method 1
    rio('dstfile') < [ rio('src1'), rio('src2'), rio('src3') ]
    # method 2
    rio('dstfile') < rio('src1') << rio('src2') << rio('src3')
    
  • Copy a web page into a file

    # method 1
    rio('http://ruby-doc.org/') > rio('afile')
    # method 2
    rio('afile') < rio('http://ruby-doc.org/')
    # method 3
    rio('afile').print!(rio('http://ruby-doc.org/').contents)
    
  • Append the output of the daytime server running on the localhost to a file

    # method 1
    rio("tcp://localhost:daytime") >> rio('afile')
    # method 2
    rio("tcp:",'localhost','daytime') >> rio('afile')
    # method 3
    rio('afile') << rio("tcp://:daytime")
    # method 4
    rio('afile') << rio("tcp://:13")
    
  • Copy the first line and all lines containing ‘http:’ to a file

    # method 1
    rio('srcfile').lines(0,/http:/) > rio('dstfile')
    # method 2
    rio('dstfile') < rio('srcfile').lines(0,/http:/)
    # method 3
    rio('dstfile') < rio('srcfile').lines[0,/http:/]
    # method 4
    
  • Create a gzipped copy of a file

    # method 1
    rio('afile') > rio('afile.gz').gzip
    # method 2
    rio('afile.gz').gzip < rio('afile')
    # method 3
    rio('afile.gz').gzip.print!( rio('afile').contents )
    
  • Create an ungzipped copy of a gzipped file

    # method 1
    rio('afile') < rio('afile.gz').gzip
    # method 2
    rio('afile.gz').gzip > rio('afile')
    # method 3
    rio('afile').print!( rio('afile.gz').gzip.contents )
    
  • Copy the first 100 lines of gzipped file on a webserver into a local file

    # method 1
    rio('http://aserver/afile.gz').gzip.lines(0...100) > rio('afile')
    
  • Create a file composed of a header from another file, the output of the ‘ps’ command, some text and its creation time pulled from the daytime server running on your localhost

    # method 1
    rio('out') < [ rio('header'), rio(?-,'ps'), "Created on ", rio('tcp://:daytime') ]
    # method 2
    rio('out') < rio('header') << rio(?-,'ps') << "Created on: " << rio("tcp://:daytime")
    

Reading multiple files

ario = rio('adir')
string = ""
array = []
  • Count the lines of code in a directory tree of ruby source files

    # method 1
    cnt = ario.all.files('*.rb').chomp.skiplines(/^\s*#/,/^\s*$/).inject(0) { |sum,l|  sum += 1 }
    # method 2
    cnt = ario.all.files('*.rb').chomp.skiplines[/^\s*#/,/^\s*$/].size
    
  • Concatanate the contents of all .txt files in a directory into an array

    # method 1
    array = ario.lines.files['*.txt']
    # method 2
    array = ario.files('*.txt').lines[]
    # method 3
    ario.files('*.txt').lines > array
    
  • Concatanate the first line of all .txt files in a directory into an array

    # method 1
    array = ario.lines(0).files['*.txt']
    # method 2
    array = ario.files('*.txt').lines[0]
    # method 3
    ario.files('*.txt').lines(0) > array
    
  • Copy all .txt files (but only their first ten lines) in a directory into another directiory

    # method 1
    ario.files('*.txt').lines(0...10) > rio('another_dir')
    

Read and write using Standard IO

string = ""
array = []
  • Prompt for input and return what was typed

    # method 1
    ans = rio(?-).chomp.print("Type Something: ").gets
    # method 2
    stdio = rio(?-).chomp
    ans = stdio.print("Type Something: ").gets
    
  • Create a Rio tied to stdin or stdout, depending on how it is used

    stdio = rio(?-)
    
  • Create a Rio tied to stderr

    stderr = rio(?=)
    
  • Write a string to stdout

    # method 1
    rio(?-).puts("Hello World")
    # method 2
    rio(?-) << "Hello World\n"
    # method 3
    rio(?-) < "Hello World\n"
    
  • Read a string from stdin with the input chomped

    # method 1
    ans = rio(?-).chomp.gets
    # method 2
    stdio = rio(?-).chomp
    ans = stdio.gets
    
  • Read from stdin until end of file with the result going into a string

    # method 1
    rio(?-) >> string
    # method 2
    rio(?-) > string
    
  • Read from stdin until end of file with the chomped lines going into an array

    # method 1
    rio(?-).chomp >> array
    # method 2
    rio(?-).chomp > array
    
  • Read from stdin until end of file with the result going into a file

    # method 1
    rio(?-) > rio('afile')
    # method 2
    rio('afile') < rio(?-)
    
  • Read from stdin until end of file with the result appended to a file

    # method 1
    rio(?-) >> rio('afile')
    # method 2
    rio('afile') << rio(?-)
    
  • Write a message to stderr

    # method 1
    rio(?=).puts("Hello Error")
    # method 2
    rio(?=) << "Hello Error\n"
    # method 3
    rio(?=) < "Hello Error\n"
    
  • Dump a file to stdout

    # method 1
    rio(?-) << rio('afile')
    # method 2
    rio('afile') >> rio(?-)
    # method 3
    rio('afile') > rio(?-)
    # method 4
    rio(?-) < rio('afile')
    # method 5
    rio(?-).print(rio('afile').contents)
    
  • Emulate a simplified unix ‘head’ command which reads from stdin and writes the first 10 lines to stdout

    # method 1
    rio(?-).lines(0..9) > rio(?-)
    

Reading and writing from processes as one might do with popen

  • Read the output of the ‘ps’ command into an array without the header line or the line representing the ‘ps’ command itself

    ps =  rio(?-,'ps -a').skiplines[0,/ps$/]
    
  • Run an external program, copying its input from one location and its output to another, and make it look very much like a shell command.

    infile = rio(?","Hello Kitty\n")
    outfile = rio('out.txt')
    
    # method 1
    cat = rio(?-,'cat').w!
    cat <infile >outfile
    
    # method 2
    infile | 'cat' | outfile
    

Renaming and moving files

string = ""
array = []
  • Rename the file ‘a’ to ‘b’

    # method 1
    rio('a').rename('b')
    # method 2
    rio('a').rename.filename = 'b'
    
  • Rename a file and leave the Rio referencing the files old name

    ario = rio('a')
    # method 1
    ario.rename('b')
    
  • Rename a file and change the Rio to reference the new file name

    ario = rio('a')
    # method 1
    ario.rename!('b')
    
  • Rename the file ‘index.htm’ to ‘index.html’

    # method 1
    rio('index.htm').rename('index.html')
    # method 2
    rio('index.htm').rename.extname = '.html'
    
  • Rename the file ‘index.html’ to ‘welcome.html’

    # method 1
    rio('index.html').rename('welecome.html')
    # method 2
    rio('index.htm').rename.basename = 'welcome'
    
  • Move a file from directory ‘src’ to directory ‘dst’

    # method 1
    rio('src/afile').rename('dst/afile')
    # method 2
    rio('src/afile').rename.dirname = 'dst'
    
  • Change a file to have the extension ‘.html’ leaving the rest of it as is

    # method 1
    ario.rename.extname = '.html'
    
  • Change a files basename to ‘zippy’ without changing its extension

    # method 1
    ario.rename.basename = 'zippy'
    
  • Change a file ending with ‘.tar.gz’ to end with ‘.tgz’

    # method 1
    ario.rename.ext('.tar.gz').extname = '.tgz'
    
  • Change the extension of all files with the extension ‘.htm’ in a directory to have the extension ‘.html’

    # method 1
    rio('adir').rename.files('*.htm') do |htmfile|
      htmlfile.extname = '.html'
    end
    # method 2
    rio('adir').files('*.htm') do |htmfile|
      htmlfile.rename.extname = '.html'
    end
    
  • Change the extension of all files with the extension ‘.htm’ in a directory and its subdirectories to have the extension ‘.html’

    # method 1
    rio('adir').rename.all.files('*.htm') do |htmfile|
      htmfile.extname = '.html'
    end
    # method 2
    rio('adir').all.files('*.htm') do |htmfile|
      htmfile.rename.extname = '.html'
    end
    
  • Move a file in an arbitrary directory into the current working directory.

    # method 1
    rio('arb/i/trary/di/rec/tory/afile').rename.dirname = '.'
    

Manipulate a Rio’s path

string = ""
array = []
  • Create a Rio with an additional subdirectory appended

    ap = rio('adir')
    # method 1
    ap /= 'subdirectory'   
    # method 2
    ap = ap.join('subdirectory')
    # method 3
    ap = rio(ap,'subdirectory')
    # method 4
    
  • Create a Rio from an array of subdirectories

    dirs = ['adir','subdir1','subdir2']
    # method 1
    ario = rio(dirs)
    
  • Create an array of subdirectories from a Rio

    # method 1
    anarray = rio('adir/subdir1/subdir2').split
    
  • Append a string to a path

    # method 1
    ario = rio('apath') + astring
    # method 2
    ario = rio('apath')
    ario += astring
    
  • create a directory ‘links’ with a symlink pointing to each .rb file in directory ‘lib’ (including subdirectories)

    lib = rio('lib')
    links = rio('links').delete!.mkdir
    lib.all.files("*.rb") do |f|
      f.symlink( f.dirname.sub(/^#{lib}/,links).mkdir )
    end
    

Suggested Reading

  • RIO::Doc::SYNOPSIS

  • RIO::Doc::INTRO

  • RIO::Rio