rio 0.4.2 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/Gemfile +4 -0
- data/{COPYING → LICENSE} +3 -0
- data/README +20 -27
- data/Rakefile +48 -277
- data/lib/rio.rb +63 -24
- data/lib/rio/.document +5 -0
- data/lib/rio/abstract_method.rb +3 -14
- data/lib/rio/alturi.rb +507 -0
- data/lib/rio/alturi/algorithm.rb +313 -0
- data/lib/rio/alturi/cached_fields.rb +68 -0
- data/lib/rio/alturi/escape.rb +82 -0
- data/lib/rio/alturi/parse.rb +75 -0
- data/lib/rio/alturi/path_parts.rb +81 -0
- data/lib/rio/alturi/regex.rb +76 -0
- data/lib/rio/alturi/uri_parts.rb +512 -0
- data/lib/rio/argv.rb +3 -14
- data/lib/rio/arraynge.rb +146 -0
- data/lib/rio/arycopy.rb +3 -14
- data/lib/rio/assert.rb +87 -15
- data/lib/rio/base.rb +7 -30
- data/lib/rio/callstr.rb +3 -14
- data/lib/rio/const.rb +3 -14
- data/lib/rio/construct.rb +4 -15
- data/lib/rio/constructor.rb +4 -19
- data/lib/rio/context.rb +17 -14
- data/lib/rio/context/autoclose.rb +3 -14
- data/lib/rio/context/binmode.rb +63 -0
- data/lib/rio/context/copying.rb +3 -14
- data/lib/rio/context/cxx.rb +3 -14
- data/lib/rio/context/dir.rb +5 -15
- data/lib/rio/context/encoding.rb +84 -0
- data/lib/rio/context/gzip.rb +3 -14
- data/lib/rio/context/methods.rb +8 -17
- data/lib/rio/context/skip.rb +3 -14
- data/lib/rio/context/stream.rb +3 -14
- data/lib/rio/cp.rb +5 -20
- data/lib/rio/cxuri.rb +67 -0
- data/lib/rio/dbg/trace_states.rb +18 -0
- data/lib/rio/def.rb +3 -14
- data/lib/rio/dir.rb +9 -18
- data/lib/rio/doc.rb +3 -14
- data/lib/rio/doc/EXAMPLES.rb +256 -269
- data/lib/rio/doc/HOWTO.rb +685 -707
- data/lib/rio/doc/INDEX.rb +261 -282
- data/lib/rio/doc/INTRO.rb +1029 -1040
- data/lib/rio/doc/OPTIONAL.rb +77 -103
- data/lib/rio/doc/SYNOPSIS.rb +122 -143
- data/lib/rio/entrysel.rb +3 -14
- data/lib/rio/exception.rb +4 -14
- data/lib/rio/exception/copy.rb +3 -14
- data/lib/rio/exception/notimplemented.rb +3 -14
- data/lib/rio/exception/notsupported.rb +3 -14
- data/lib/rio/exception/open.rb +3 -14
- data/lib/rio/exception/state.rb +3 -14
- data/lib/rio/ext.rb +14 -17
- data/lib/rio/ext/csv.rb +25 -304
- data/lib/rio/ext/csv/csv-legacy.rb +344 -0
- data/lib/rio/ext/csv/csv.rb +359 -0
- data/lib/rio/ext/csv/filter.rb +209 -0
- data/lib/rio/ext/if.rb +3 -14
- data/lib/rio/ext/mp3info.rb +3 -14
- data/lib/rio/ext/splitlines.rb +3 -14
- data/lib/rio/ext/yaml.rb +3 -14
- data/lib/rio/ext/yaml/doc.rb +3 -14
- data/lib/rio/ext/yaml/tie.rb +3 -14
- data/lib/rio/ext/zipfile.rb +3 -14
- data/lib/rio/ext/zipfile/fs.rb +3 -14
- data/lib/rio/ext/zipfile/rl.rb +3 -14
- data/lib/rio/ext/zipfile/rootdir.rb +3 -14
- data/lib/rio/ext/zipfile/state.rb +3 -14
- data/lib/rio/ext/zipfile/wrap.rb +3 -14
- data/lib/rio/factory.rb +96 -213
- data/lib/rio/fibpipe.rb +373 -0
- data/lib/rio/file.rb +8 -17
- data/lib/rio/filter.rb +4 -15
- data/lib/rio/filter/closeoneof.rb +3 -14
- data/lib/rio/filter/gzip.rb +18 -27
- data/lib/rio/fs.rb +172 -0
- data/lib/rio/fs/base.rb +3 -14
- data/lib/rio/fs/impl.rb +3 -14
- data/lib/rio/fs/native.rb +3 -14
- data/lib/rio/fs/stream.rb +3 -14
- data/lib/rio/fs/url.rb +3 -14
- data/lib/rio/ftp/conncache.rb +16 -18
- data/lib/rio/ftp/dir.rb +4 -15
- data/lib/rio/ftp/fs.rb +62 -42
- data/lib/rio/fwd.rb +15 -0
- data/lib/rio/grande.rb +4 -15
- data/lib/rio/handle.rb +3 -45
- data/lib/rio/if.rb +15 -20
- data/lib/rio/if/basic.rb +3 -36
- data/lib/rio/if/csv.rb +7 -20
- data/lib/rio/if/dir.rb +9 -21
- data/lib/rio/if/file.rb +6 -19
- data/lib/rio/if/fileordir.rb +18 -29
- data/lib/rio/if/grande.rb +109 -120
- data/lib/rio/if/grande_entry.rb +5 -18
- data/lib/rio/if/grande_stream.rb +29 -42
- data/lib/rio/if/internal.rb +15 -16
- data/lib/rio/if/path.rb +35 -47
- data/lib/rio/if/rubyio.rb +35 -47
- data/lib/rio/if/string.rb +3 -16
- data/lib/rio/if/temp.rb +3 -16
- data/lib/rio/if/test.rb +8 -20
- data/lib/rio/if/yaml.rb +16 -29
- data/lib/rio/ioh.rb +35 -34
- data/lib/rio/iomode.rb +3 -14
- data/lib/rio/ios/fail.rb +3 -14
- data/lib/rio/ios/generic.rb +3 -14
- data/lib/rio/ios/mode.rb +3 -14
- data/lib/rio/ios/null.rb +3 -14
- data/lib/rio/iowrap.rb +3 -14
- data/lib/rio/kernel.rb +4 -17
- data/lib/rio/local.rb +3 -14
- data/lib/rio/match.rb +3 -14
- data/lib/rio/matchrecord.rb +8 -17
- data/lib/rio/no_warn.rb +3 -14
- data/lib/rio/nullio.rb +3 -14
- data/lib/rio/open3.rb +3 -16
- data/lib/rio/ops.rb +33 -0
- data/lib/rio/ops/construct.rb +3 -14
- data/lib/rio/ops/create.rb +11 -25
- data/lib/rio/ops/dir.rb +17 -24
- data/lib/rio/ops/either.rb +28 -31
- data/lib/rio/ops/file.rb +29 -26
- data/lib/rio/ops/path.rb +65 -34
- data/lib/rio/ops/stream.rb +13 -15
- data/lib/rio/ops/stream/input.rb +59 -28
- data/lib/rio/ops/stream/output.rb +4 -14
- data/lib/rio/ops/stream/read.rb +4 -15
- data/lib/rio/ops/stream/write.rb +3 -14
- data/lib/rio/ops/symlink.rb +6 -15
- data/lib/rio/path.rb +10 -17
- data/lib/rio/path/reset.rb +3 -14
- data/lib/rio/piper.rb +3 -27
- data/lib/rio/piper/cp.rb +50 -27
- data/lib/rio/prompt.rb +3 -14
- data/lib/rio/rectype.rb +8 -16
- data/lib/rio/rl/base.rb +12 -25
- data/lib/rio/rl/builder.rb +25 -24
- data/lib/rio/rl/chmap.rb +3 -16
- data/lib/rio/rl/fs2url.rb +5 -16
- data/lib/rio/rl/ioi.rb +3 -14
- data/lib/rio/rl/path.rb +14 -25
- data/lib/rio/rl/pathmethods.rb +3 -14
- data/lib/rio/rl/uri.rb +18 -35
- data/lib/rio/rl/withpath.rb +36 -53
- data/lib/rio/rrl/base.rb +75 -0
- data/lib/rio/rrl/builder.rb +122 -0
- data/lib/rio/rrl/chmap.rb +53 -0
- data/lib/rio/rrl/ioi.rb +78 -0
- data/lib/rio/rrl/path.rb +117 -0
- data/lib/rio/rrl/withpath.rb +269 -0
- data/lib/rio/scheme/aryio.rb +3 -14
- data/lib/rio/scheme/cmdio.rb +73 -42
- data/lib/rio/scheme/cmdpipe.rb +122 -59
- data/lib/rio/scheme/fd.rb +19 -33
- data/lib/rio/scheme/ftp.rb +34 -40
- data/lib/rio/scheme/http.rb +13 -22
- data/lib/rio/scheme/null.rb +6 -17
- data/lib/rio/scheme/path.rb +60 -71
- data/lib/rio/scheme/stderr.rb +9 -21
- data/lib/rio/scheme/stdio.rb +14 -26
- data/lib/rio/scheme/strio.rb +37 -38
- data/lib/rio/scheme/sysio.rb +20 -32
- data/lib/rio/scheme/tcp.rb +3 -14
- data/lib/rio/scheme/temp.rb +103 -92
- data/lib/rio/state.rb +85 -67
- data/lib/rio/state/data.rb +55 -0
- data/lib/rio/state/error.rb +7 -27
- data/lib/rio/stream.rb +46 -19
- data/lib/rio/stream/base.rb +14 -14
- data/lib/rio/stream/duplex.rb +64 -26
- data/lib/rio/stream/open.rb +9 -19
- data/lib/rio/symantics.rb +3 -14
- data/lib/rio/tempdir.rb +8 -17
- data/lib/rio/to_rio.rb +3 -16
- data/lib/rio/to_rio/all.rb +3 -14
- data/lib/rio/to_rio/array.rb +3 -14
- data/lib/rio/to_rio/io.rb +3 -14
- data/lib/rio/to_rio/object.rb +3 -14
- data/lib/rio/to_rio/string.rb +3 -14
- data/lib/rio/uri/file.rb +98 -153
- data/lib/rio/uriref.rb +144 -0
- data/lib/rio/util.rb +3 -14
- data/lib/rio/version.rb +4 -15
- data/misc/clean-heading-comments.rb +39 -0
- data/misc/fixdoclinks.rb +36 -0
- data/misc/update-copyright.rb +17 -0
- data/rio.gemspec +31 -0
- data/test/alturi/tc/create.rb +24 -0
- data/test/alturi/tc/empty.rb +13 -0
- data/test/alturi/tc/encoding.rb +73 -0
- data/test/alturi/tc/file_test.rb +335 -0
- data/test/alturi/tc/ftp_alturi.rb +147 -0
- data/test/alturi/tc/generic_test.rb +335 -0
- data/test/alturi/tc/http_test.rb +359 -0
- data/test/alturi/tc/path_parts_test.rb +215 -0
- data/test/alturi/tc/rfc_test.rb +83 -0
- data/test/alturi/tc/uri_parts_authority.rb +129 -0
- data/test/alturi/tc/uri_parts_test.rb +473 -0
- data/test/alturi/tc/uri_parts_userinfo.rb +140 -0
- data/test/alturi/tests.rb +27 -0
- data/test/base_test.rb +18 -0
- data/test/bin/demo_chdir.rb +60 -0
- data/test/bin/elipsis.rb +11 -0
- data/test/env.sh +4 -0
- data/test/ftp/initftpfiles.rb +1 -0
- data/test/ftp/tc/anon_copy_data.rb +31 -0
- data/test/ftp/tc/anon_misc.rb +109 -0
- data/test/ftp/tc/anon_read.rb +99 -0
- data/test/ftp/tc/anon_special.rb +37 -0
- data/test/ftp/tc/anon_write.rb +68 -0
- data/test/ftp/tc/copy.rb +35 -0
- data/test/ftp/tc/empty.rb +16 -0
- data/test/ftp/tc/ftp2ftp.rb +42 -0
- data/test/ftp/tc/ftp_fs.rb +333 -0
- data/test/ftp/testdef.rb +7 -2
- data/test/ftp/tests.rb +24 -0
- data/test/gem_runtests.rb +1 -1
- data/test/http/copy-from-http.rb +0 -1
- data/test/http/def.rb +20 -0
- data/test/http/tc/copy_from_http.rb +128 -0
- data/test/http/tc/empty.rb +14 -0
- data/test/http/tc/uri_meta.rb +52 -0
- data/test/http/tests.rb +19 -0
- data/test/lib/assertions.rb +7 -0
- data/test/lib/run_tests.rb +26 -0
- data/test/lib/temp_server.rb +7 -4
- data/test/methods/test_suite.rb +108 -0
- data/test/platform.rb +5 -0
- data/test/qpdir.rb +2 -0
- data/test/rio/scheme.rb +49 -0
- data/test/rio/tc/pathparts.rb +61 -0
- data/test/riotest/test_suite.rb +33 -0
- data/test/riotest/unit_test.rb +118 -0
- data/test/riotest/util.rb +23 -0
- data/test/runalltests.rb +1 -1
- data/test/runftptests.rb +2 -7
- data/test/runhttp.rb +4 -2
- data/test/runhttptests.rb +6 -5
- data/test/runtests.rb +66 -37
- data/test/srv/www/htdocs/riotest/dir/index.html +11 -0
- data/test/srv/www/htdocs/riotest/hw.html +8 -0
- data/test/srv/www/htdocs/riotest/lines.txt.gz +0 -0
- data/test/tc/abs2.rb +358 -0
- data/test/tc/all.rb +17 -10
- data/test/tc/base2.rb +8 -7
- data/test/tc/clearsel.rb +3 -2
- data/test/tc/closeoneof.rb +14 -15
- data/test/tc/cmdio.rb +193 -0
- data/test/tc/cmdpipe.rb +258 -63
- data/test/tc/copy.rb +3 -2
- data/test/tc/copyarray.rb +0 -4
- data/test/tc/copydest.rb +2 -3
- data/test/tc/copydir.rb +5 -1
- data/test/tc/copydir2.rb +68 -0
- data/test/tc/create.rb +4 -9
- data/test/tc/csv.rb +38 -119
- data/test/tc/csv2.rb +38 -57
- data/test/tc/csv_columns.rb +210 -8
- data/test/tc/csv_gzip.rb +78 -0
- data/test/tc/csv_headers.rb +134 -0
- data/test/tc/csvutil.rb +53 -16
- data/test/tc/dir.rb +3 -4
- data/test/tc/dir_iter.rb +3 -1
- data/test/tc/dirent.rb +8 -7
- data/test/tc/each.rb +62 -47
- data/test/tc/each_break.rb +67 -25
- data/test/tc/edf.rb +3 -2
- data/test/tc/empty.rb +6 -4
- data/test/tc/encoding.rb +30 -0
- data/test/tc/entary.rb +6 -5
- data/test/tc/eq.rb +2 -2
- data/test/tc/expand_path.rb +14 -14
- data/test/tc/ext.rb +7 -7
- data/test/tc/fileno.rb +3 -2
- data/test/tc/files_select.rb +1 -1
- data/test/tc/getrec.rb +2 -3
- data/test/tc/gzip.rb +5 -3
- data/test/tc/likeio.rb +5 -5
- data/test/tc/lineno.rb +1 -1
- data/test/tc/lines.rb +4 -4
- data/test/tc/misc.rb +29 -171
- data/test/tc/nolines.rb +4 -2
- data/test/tc/noqae.rb +12 -10
- data/test/tc/overload.rb +1 -2
- data/test/tc/pa.rb +25 -24
- data/test/tc/path_parts.rb +54 -20
- data/test/tc/paths.rb +3 -2
- data/test/tc/piper.rb +32 -31
- data/test/tc/programs_util.rb +9 -9
- data/test/tc/qae.rb +9 -8
- data/test/tc/qae_riovar.rb +9 -8
- data/test/tc/records.rb +3 -2
- data/test/tc/rename.rb +4 -4
- data/test/tc/riorl.rb +19 -19
- data/test/tc/rlparts.ans.yml +1161 -0
- data/test/tc/splitlines.rb +1 -1
- data/test/tc/splitpath.rb +9 -8
- data/test/tc/strio.rb +73 -0
- data/test/tc/symlink.rb +3 -2
- data/test/tc/symlink0.rb +4 -3
- data/test/tc/symlink1.rb +4 -3
- data/test/tc/temp.rb +40 -26
- data/test/tc/tempdir.rb +12 -12
- data/test/tc/testcase.rb +45 -31
- data/test/tc/tonl.rb +0 -1
- data/test/tc/truncate.rb +111 -13
- data/test/tc/yaml.rb +1 -1
- data/test/test_suite.rb +31 -0
- data/test/tests.rb +35 -0
- data/test/tsuite.rb +19 -0
- data/test/uriref/tc/basic.rb +171 -0
- data/test/uriref/tc/build.rb +30 -0
- data/test/uriref/tc/empty.rb +13 -0
- data/test/uriref/tc/route.rb +72 -0
- data/test/uriref/tests.rb +16 -0
- metadata +356 -424
- data/ChangeLog +0 -3122
- data/VERSION +0 -1
- data/build_doc.rb +0 -94
- data/doc/ANNOUNCE +0 -157
- data/doc/RELEASE_NOTES +0 -308
- data/doc/RIOIS +0 -215
- data/doc/generators/template/html/rio.css +0 -428
- data/doc/generators/template/html/rio.rb +0 -523
- data/doc/generators/template/html/ugly.rb +0 -132
- data/doc/pkg_def.rb +0 -60
- data/doc/rdoc/classes/Kernel.html +0 -133
- data/doc/rdoc/classes/Kernel.src/M000234.html +0 -18
- data/doc/rdoc/classes/RIO.html +0 -625
- data/doc/rdoc/classes/RIO.src/M000001.html +0 -18
- data/doc/rdoc/classes/RIO.src/M000002.html +0 -18
- data/doc/rdoc/classes/RIO.src/M000003.html +0 -18
- data/doc/rdoc/classes/RIO/Doc.html +0 -149
- data/doc/rdoc/classes/RIO/Doc/EXAMPLES.html +0 -432
- data/doc/rdoc/classes/RIO/Doc/HOWTO.html +0 -1084
- data/doc/rdoc/classes/RIO/Doc/INDEX.html +0 -368
- data/doc/rdoc/classes/RIO/Doc/INTRO.html +0 -1529
- data/doc/rdoc/classes/RIO/Doc/OPTIONAL.html +0 -221
- data/doc/rdoc/classes/RIO/Doc/SYNOPSIS.html +0 -336
- data/doc/rdoc/classes/RIO/IF.html +0 -165
- data/doc/rdoc/classes/RIO/IF/CSV.html +0 -203
- data/doc/rdoc/classes/RIO/IF/CSV.src/M000129.html +0 -19
- data/doc/rdoc/classes/RIO/IF/CSV.src/M000130.html +0 -16
- data/doc/rdoc/classes/RIO/IF/CSV.src/M000131.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Dir.html +0 -343
- data/doc/rdoc/classes/RIO/IF/Dir.src/M000045.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Dir.src/M000046.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Dir.src/M000047.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Dir.src/M000048.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Dir.src/M000049.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Dir.src/M000050.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Dir.src/M000051.html +0 -16
- data/doc/rdoc/classes/RIO/IF/File.html +0 -223
- data/doc/rdoc/classes/RIO/IF/File.src/M000216.html +0 -16
- data/doc/rdoc/classes/RIO/IF/File.src/M000217.html +0 -16
- data/doc/rdoc/classes/RIO/IF/File.src/M000218.html +0 -16
- data/doc/rdoc/classes/RIO/IF/File.src/M000219.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.html +0 -572
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000117.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000118.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000119.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000120.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000121.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000122.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000123.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000124.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000125.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000126.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000127.html +0 -16
- data/doc/rdoc/classes/RIO/IF/FileOrDir.src/M000128.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.html +0 -1376
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000052.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000053.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000054.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000055.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000056.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000057.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000058.html +0 -21
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000059.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000060.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000061.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000062.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000063.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000064.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000065.html +0 -21
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000066.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000067.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000068.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000069.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Grande.src/M000070.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.html +0 -810
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000107.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000108.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000109.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000110.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000111.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000112.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000113.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000114.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000115.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeEntry.src/M000116.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.html +0 -1513
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000071.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000072.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000073.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000074.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000075.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000076.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000077.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000078.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000079.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000080.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000081.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000082.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000083.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000084.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000085.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000086.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000087.html +0 -19
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000088.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000089.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000090.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000091.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000092.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000093.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000094.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000095.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000096.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000097.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000098.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000099.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000100.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000101.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000102.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000103.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000104.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000105.html +0 -16
- data/doc/rdoc/classes/RIO/IF/GrandeStream.src/M000106.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.html +0 -999
- data/doc/rdoc/classes/RIO/IF/Path.src/M000132.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000133.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000134.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000135.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000136.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000137.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000138.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000139.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000140.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000141.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000142.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000143.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000144.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000145.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000146.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000147.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000148.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000149.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000150.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000151.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000152.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000153.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000154.html +0 -18
- data/doc/rdoc/classes/RIO/IF/Path.src/M000155.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000156.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000157.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000158.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000159.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000160.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000161.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000162.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Path.src/M000163.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.html +0 -1416
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000004.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000005.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000006.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000007.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000008.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000009.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000010.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000011.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000012.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000013.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000014.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000015.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000016.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000017.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000018.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000019.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000020.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000021.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000022.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000023.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000024.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000025.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000026.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000027.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000028.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000029.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000030.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000031.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000032.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000033.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000034.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000035.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000036.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000037.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000038.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000039.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000040.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000041.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000042.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000043.html +0 -16
- data/doc/rdoc/classes/RIO/IF/RubyIO.src/M000044.html +0 -16
- data/doc/rdoc/classes/RIO/IF/String.html +0 -203
- data/doc/rdoc/classes/RIO/IF/String.src/M000213.html +0 -16
- data/doc/rdoc/classes/RIO/IF/String.src/M000214.html +0 -16
- data/doc/rdoc/classes/RIO/IF/String.src/M000215.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.html +0 -990
- data/doc/rdoc/classes/RIO/IF/Test.src/M000177.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000178.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000179.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000180.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000181.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000182.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000183.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000184.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000185.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000186.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000187.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000188.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000189.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000190.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000191.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000192.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000193.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000194.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000195.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000196.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000197.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000198.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000199.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000200.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000201.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000202.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000203.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000204.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000205.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000206.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000207.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000208.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000209.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000210.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000211.html +0 -16
- data/doc/rdoc/classes/RIO/IF/Test.src/M000212.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.html +0 -517
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000164.html +0 -19
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000165.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000166.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000167.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000168.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000169.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000170.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000171.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000172.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000173.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000174.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000175.html +0 -16
- data/doc/rdoc/classes/RIO/IF/YAML.src/M000176.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.html +0 -508
- data/doc/rdoc/classes/RIO/Rio.src/M000220.html +0 -18
- data/doc/rdoc/classes/RIO/Rio.src/M000221.html +0 -20
- data/doc/rdoc/classes/RIO/Rio.src/M000222.html +0 -27
- data/doc/rdoc/classes/RIO/Rio.src/M000223.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.src/M000225.html +0 -19
- data/doc/rdoc/classes/RIO/Rio.src/M000226.html +0 -20
- data/doc/rdoc/classes/RIO/Rio.src/M000227.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.src/M000228.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.src/M000229.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.src/M000230.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.src/M000231.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.src/M000232.html +0 -16
- data/doc/rdoc/classes/RIO/Rio.src/M000233.html +0 -16
- data/doc/rdoc/created.rid +0 -1
- data/doc/rdoc/files/README.html +0 -232
- data/doc/rdoc/files/lib/rio/constructor_rb.html +0 -141
- data/doc/rdoc/files/lib/rio/doc/EXAMPLES_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/doc/HOWTO_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/doc/INDEX_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/doc/INTRO_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/doc/OPTIONAL_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/doc/SYNOPSIS_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/basic_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/csv_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/dir_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/file_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/fileordir_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/grande_entry_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/grande_rb.html +0 -141
- data/doc/rdoc/files/lib/rio/if/grande_stream_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/internal_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/path_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/rubyio_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/string_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/temp_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/test_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/if/yaml_rb.html +0 -134
- data/doc/rdoc/files/lib/rio/kernel_rb.html +0 -142
- data/doc/rdoc/files/lib/rio_rb.html +0 -153
- data/doc/rdoc/fr_class_index.html +0 -49
- data/doc/rdoc/fr_file_index.html +0 -51
- data/doc/rdoc/fr_method_index.html +0 -260
- data/doc/rdoc/index.html +0 -30
- data/doc/rdoc/rdoc-style.css +0 -428
- data/doc/rfc1738.txt +0 -1403
- data/doc/rfc959.txt +0 -3933
- data/ex/catcsv.rb +0 -64
- data/ex/colx.rb +0 -8
- data/ex/findinruby +0 -15
- data/ex/findruby +0 -14
- data/ex/passwd_report.rb +0 -8
- data/ex/prompt.rb +0 -25
- data/ex/rgb.txt.gz +0 -0
- data/ex/riocat +0 -42
- data/ex/riogunzip +0 -31
- data/ex/riogzip +0 -24
- data/ex/rioprompt.rb +0 -10
- data/ex/targz2zip +0 -17
- data/ex/tonl +0 -10
- data/setup.rb +0 -1360
- data/test/ftp/all.rb +0 -9
- data/test/ftp/anon_copy_data.rb +0 -36
- data/test/ftp/anon_misc.rb +0 -124
- data/test/ftp/anon_read.rb +0 -105
- data/test/ftp/anon_special.rb +0 -68
- data/test/ftp/anon_write.rb +0 -70
- data/test/ftp/ftp2ftp.rb +0 -51
- data/test/tc/abs.rb +0 -355
data/lib/rio/doc/INTRO.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#--
|
2
|
-
#
|
3
|
-
# Copyright (c) 2005
|
2
|
+
# ===========================================================================
|
3
|
+
# Copyright (c) 2005-2012 Christopher Kleckner
|
4
4
|
# All rights reserved
|
5
5
|
#
|
6
6
|
# This file is part of the Rio library for ruby.
|
@@ -18,1050 +18,1039 @@
|
|
18
18
|
# You should have received a copy of the GNU General Public License
|
19
19
|
# along with Rio; if not, write to the Free Software
|
20
20
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
-
#
|
21
|
+
# ===========================================================================
|
22
22
|
#++
|
23
23
|
#
|
24
|
-
# To create the documentation for Rio run the command
|
25
|
-
# ruby build_doc.rb
|
26
|
-
# from the distribution directory.
|
27
|
-
#
|
28
|
-
# Suggested Reading
|
29
|
-
# * RIO::Doc::SYNOPSIS
|
30
|
-
# * RIO::Doc::INTRO
|
31
|
-
# * RIO::Doc::HOWTO
|
32
|
-
# * RIO::Doc::EXAMPLES
|
33
|
-
# * RIO::Rio
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
24
|
module RIO
|
38
25
|
module Doc
|
39
|
-
=begin rdoc
|
40
|
-
|
41
|
-
= Rio - Ruby I/O Facilitator
|
42
|
-
|
43
|
-
Rio is a facade for most of the standard ruby classes that deal with I/O;
|
44
|
-
providing a simple, intuitive, succinct interface to the functionality
|
45
|
-
provided by IO, File, Dir, Pathname, FileUtils, Tempfile, StringIO, OpenURI
|
46
|
-
and others. Rio also provides an application level interface which allows many
|
47
|
-
common I/O idioms to be expressed succinctly.
|
48
|
-
|
49
|
-
|
50
|
-
Rio functionality can be broadly broken into three categories
|
51
|
-
* path manipulation
|
52
|
-
* file system access
|
53
|
-
* stream manipulation
|
54
|
-
|
55
|
-
Which methods are available to a given Rio, depends on the underlying
|
56
|
-
object.
|
57
|
-
|
58
|
-
A Rio generally does not need to be opened or have its mode specified.
|
59
|
-
Most of Rio's methods simply configure it. When an actual IO
|
60
|
-
operation is specified, Rio determines how to open it based on the
|
61
|
-
object it is opening, the operation it is performing, and the options
|
62
|
-
specified.
|
63
|
-
|
64
|
-
Rio configuration methods return the Rio for easy chaining and regard
|
65
|
-
the presence of a block as an implied +each+.
|
66
|
-
|
67
|
-
== Using a Rio
|
68
|
-
|
69
|
-
Using a Rio can be described as having 3 steps:
|
70
|
-
* Creating a Rio
|
71
|
-
* Configuring a Rio
|
72
|
-
* Rio I/O
|
73
|
-
|
74
|
-
=== Creating a Rio
|
75
|
-
|
76
|
-
Rio extends Kernel with one function +rio+, its constructor. This
|
77
|
-
function is overloaded to create any type of Rio. +rio+ looks at the
|
78
|
-
class and sometimes the value of its first argument to create an
|
79
|
-
internal representation of the resource specified, additional
|
80
|
-
arguments are used as needed by the resource type. The rio constructor
|
81
|
-
does not initiate any io, it does not check for a resources existance
|
82
|
-
or type. It neither knows nor cares what can be done with this Rio.
|
83
|
-
Using methods like <tt>respond_to?</tt> are meaningless at best and usually
|
84
|
-
misleading.
|
85
|
-
|
86
|
-
For purposes of discussion, we divide Rios into two catagories, those
|
87
|
-
that have a path and those that don't.
|
88
|
-
|
89
|
-
==== Creating a Rio that has a path
|
90
|
-
|
91
|
-
To create a Rio that has a path the arguments to +rio+ may be:
|
92
|
-
|
93
|
-
* a string representing the entire path. The separator used for Rios
|
94
|
-
is as specified in RFC1738 ('/').
|
95
|
-
|
96
|
-
rio('adir/afile')
|
97
|
-
|
98
|
-
* a string representing a fully qualified +file+ URI as per RFC1738
|
99
|
-
|
100
|
-
rio('file:///atopleveldir/adir/afile')
|
101
|
-
|
102
|
-
* a +URI+ object representing a +file+ or generic +URI+
|
103
|
-
|
104
|
-
rio(URI('adir/afile'))
|
105
|
-
|
106
|
-
* the components of a path as separate arguments
|
107
|
-
|
108
|
-
rio('adir','afile')
|
109
|
-
|
110
|
-
* the components of a path as an array
|
111
|
-
|
112
|
-
rio(%w/adir afile/)
|
113
|
-
|
114
|
-
* another Rio
|
115
|
-
|
116
|
-
another_rio = rio('adir/afile')
|
117
|
-
rio(another_rio)
|
118
|
-
|
119
|
-
* any object whose +to_s+ method returns one of the above
|
120
|
-
|
121
|
-
rio(Pathname.new('apath'))
|
122
|
-
|
123
|
-
* any combination of the above either as separate arguments or as
|
124
|
-
elements of an array,
|
125
|
-
|
126
|
-
another_rio = rio('dir1/dir2')
|
127
|
-
auri = URI('dir4/dir5)
|
128
|
-
rio(another_rio,'dir3',auri,'dir6/dir7')
|
129
|
-
|
130
|
-
===== Creating a Rio that refers to a web page
|
131
|
-
|
132
|
-
To create a Rio that refers to a web page the arguments to +rio+ may
|
133
|
-
be:
|
134
|
-
|
135
|
-
* a string representing a fully qualified +http+ URI
|
136
|
-
|
137
|
-
rio('http://ruby-doc.org/index.html')
|
138
|
-
|
139
|
-
* a +URI+ object representing a +http+ +URI+
|
140
|
-
|
141
|
-
rio(URI('http://ruby-doc.org/index.html'))
|
142
|
-
|
143
|
-
* either of the above with additional path elements
|
144
|
-
|
145
|
-
rio('http://www.ruby-doc.org/','core','classes/Object.html')
|
146
|
-
|
147
|
-
|
148
|
-
===== Creating a Rio that refers to a file or directory on a FTP server
|
149
|
-
|
150
|
-
To create a Rio that refers to a file on a FTP server the arguments to
|
151
|
-
+rio+ may be:
|
152
|
-
|
153
|
-
* a string representing a fully qualified +ftp+ URI
|
154
|
-
|
155
|
-
rio('ftp://user:password@ftp.example.com/afile.tar.gz')
|
156
|
-
|
157
|
-
* a +URI+ object representing a +ftp+ +URI+
|
158
|
-
|
159
|
-
rio(URI('ftp://ftp.example.com/afile.tar.gz'))
|
160
|
-
|
161
|
-
* either of the above with additional path elements
|
162
|
-
|
163
|
-
rio('ftp://ftp.gnu.org/pub/gnu','emacs','windows','README')
|
164
|
-
|
165
|
-
==== Creating Rios that do not have a path
|
166
|
-
|
167
|
-
To create a Rio without a path, the first argument to +rio+ is usually
|
168
|
-
a single character.
|
169
|
-
|
170
|
-
===== Creating a Rio that refers to a clone of your programs stdin or stdout.
|
171
|
-
|
172
|
-
<tt>rio(?-)</tt> (mnemonic: '-' is used by some Unix programs to
|
173
|
-
specify stdin or stdout in place of a file)
|
174
|
-
|
175
|
-
Just as a Rio that refers to a file, does not know whether that file
|
176
|
-
will be opened for reading or writing until an io operation is
|
177
|
-
specified, a <tt>stdio:</tt> Rio does not know whether it will connect
|
178
|
-
to stdin or stdout until an I/O operation is specified.
|
179
|
-
|
180
|
-
===== Creating a Rio that refers to a clone of your programs stderr.
|
181
|
-
|
182
|
-
<tt>rio(?=)</tt> (mnemonic: '-' refers to fileno 1, so '=' refers to
|
183
|
-
fileno 2)
|
184
|
-
|
185
|
-
===== Creating a Rio that refers to an arbitrary IO object.
|
186
|
-
|
187
|
-
an_io = ::File.new('afile')
|
188
|
-
rio(an_io)
|
189
|
-
|
190
|
-
===== Creating a Rio that refers to a file descriptor
|
191
|
-
|
192
|
-
<tt>rio(?#,fd)</tt> (mnemonic: a file descriptor is a number '#' )
|
193
|
-
|
194
|
-
an_io = ::File.new('afile')
|
195
|
-
rio(an_io)
|
196
|
-
|
197
|
-
===== Creating a Rio that refers to a StringIO object
|
198
|
-
|
199
|
-
<tt>rio(?")</tt> (mnemonic: '"' surrounds strings)
|
200
|
-
* create a Rio that refers to its own string
|
201
|
-
rio(?")
|
202
|
-
* create a Rio that refers to a string of your choosing
|
203
|
-
astring = ""
|
204
|
-
rio(?",astring)
|
205
|
-
|
206
|
-
===== Creating a Rio that refers to a Temporary object
|
207
|
-
|
208
|
-
<tt>rio(??)</tt> (mnemonic: '?' you don't know its name)
|
209
|
-
|
210
|
-
To create a temporary object that will become a file
|
211
|
-
or a directory, depending on how you use it:
|
212
|
-
rio(??)
|
213
|
-
rio(??,basename='rio',tmpdir=Dir::tmpdir)
|
214
|
-
|
215
|
-
To force it to become a directory:
|
216
|
-
rio(??).mkdir
|
217
|
-
or
|
218
|
-
rio(??).chdir
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
===== Creating a Rio that refers to an arbitrary TCPSocket
|
223
|
-
|
224
|
-
rio('tcp:',hostname,port)
|
225
|
-
or
|
226
|
-
rio('tcp://hostname:port')
|
227
|
-
|
228
|
-
===== Creating a Rio that runs an external program and connects to its stdin and stdout
|
229
|
-
|
230
|
-
<tt>rio(?-,cmd)</tt> (mnemonic: '-' is used by some Unix programs to
|
231
|
-
specify stdin or stdout in place of a file)
|
232
|
-
|
233
|
-
or
|
234
|
-
|
235
|
-
<tt>rio(?`,cmd)</tt> (mnemonic: '`' (backtick) runs an external
|
236
|
-
program in ruby)
|
237
|
-
|
238
|
-
This is Rio's interface to IO#popen
|
239
|
-
|
240
|
-
=== Path Manipulation
|
241
|
-
|
242
|
-
Rio's path manipulation methods are for the most part simply forwarded
|
243
|
-
to the File or URI classes with the return values converted to a Rio.
|
244
|
-
|
245
|
-
==== Creating a Rio from a Rio's component parts.
|
246
|
-
|
247
|
-
The Rio methods for creating a Rio from a Rio's component parts are
|
248
|
-
IF::Path#dirname, IF::Path#filename, IF::Path#basename, and IF::Path#extname. The
|
249
|
-
behavior of IF::Path#basename depends on the setting of the +ext+
|
250
|
-
configuration variable and is different from its counterpart in the
|
251
|
-
File class. The default value of the +ext+ configuration variable is
|
252
|
-
the string returned File#extname. The +ext+ configuration variable can
|
253
|
-
be changed using IF::Path#ext and IF::Path#noext and can be queried using
|
254
|
-
IF::Path#ext?. This value is used by calls to IF::Path#basename.
|
255
|
-
|
256
|
-
IF::Path#filename returns the last component of a path, and is basically
|
257
|
-
the same as +basename+ without consideration of an extension.
|
258
|
-
|
259
|
-
rio('afile.txt').basename #=> rio('afile')
|
260
|
-
rio('afile.txt').filename #=> rio('afile.txt')
|
261
|
-
|
262
|
-
ario = rio('afile.tar.gz')
|
263
|
-
ario.basename #=> rio('afile.tar')
|
264
|
-
ario.ext? #=> ".gz"
|
265
|
-
ario.ext('.tar.gz').basename #=> rio('afile')
|
266
|
-
ario.ext? #=> ".tar.gz"
|
267
|
-
|
268
|
-
==== Changing a path's component parts.
|
269
|
-
|
270
|
-
Rio also provides methods for changing the component parts of its
|
271
|
-
path. They are IF::Path#dirname=, IF::Path#filename=, IF::Path#basename=, and
|
272
|
-
IF::Path#extname=. These methods replace the part extracted as described
|
273
|
-
above with their argument.
|
274
|
-
|
275
|
-
ario = rio('dirA/dirB/afile.rb')
|
276
|
-
ario.dirname = 'dirC' # rio('dirC/afile.rb')
|
277
|
-
ario.basename = 'bfile' # rio('dirC/bfile.rb')
|
278
|
-
ario.extname = '.txt' # rio('dirC/bfile.txt')
|
279
|
-
ario.filename = 'cfile.rb' # rio('dirC/cfile.rb')
|
280
|
-
|
281
|
-
Rio also has a +rename+ mode which causes each of these to rename the
|
282
|
-
actual file system object as well as changing the Rio. This is
|
283
|
-
discussed in the section on Renaming and Moving.
|
284
|
-
|
285
|
-
==== Splitting a Rio
|
286
|
-
|
287
|
-
IF::Grande#split (or IF::Path#splitpath) returns an array of Rios, one
|
288
|
-
for each path element. (Note that this behavior differs from File#split.)
|
289
|
-
|
290
|
-
rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
|
291
|
-
|
292
|
-
The array returned is extended with a +to_rio+ method, which will put
|
293
|
-
the parts back together again.
|
294
|
-
|
295
|
-
ary = rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
|
296
|
-
ary.to_rio #=> rio('a/b/c')
|
297
|
-
|
298
|
-
==== Creating a Rio by specifying the individual parts of its path
|
299
|
-
|
300
|
-
The first way to create a Rio by specifying its parts is to use the
|
301
|
-
Rio constructor Rio#rio. Since a Rio is among the arguments the
|
302
|
-
constructor will take, the constructor can be used.
|
303
|
-
|
304
|
-
ario = rio('adir')
|
305
|
-
rio(ario,'b') #=> rio('adir/b')
|
306
|
-
|
307
|
-
IF::Path#join and IF::Path#/ do the same thing, but the operator version
|
308
|
-
<tt>/</tt> can take only one argument.
|
309
|
-
|
310
|
-
a = rio('a')
|
311
|
-
b = rio('b')
|
312
|
-
c = a.join(b) #=> rio('a/b')
|
313
|
-
c = a/b #=> rio('a/b')
|
314
|
-
|
315
|
-
The arguments to IF::Path#join and IF::Path#/ do not need to be Rios, of course
|
316
|
-
ario = rio('adir')
|
317
|
-
ario/'afile.rb' #=> rio('adir/afile.rb')
|
318
|
-
ario.join('b','c','d') #=> rio('adir/b/c/d')
|
319
|
-
ario/'b'/'c'/'d' #=> rio('adir/b/c/d')
|
320
|
-
ario /= 'e' #=> rio('adir/b/c/d/e')
|
321
|
-
|
322
|
-
==== Manipulating a Rio path by treating it as a string.
|
323
|
-
|
324
|
-
The Rio methods which treat a Rio as a string are IF::String#sub, IF::String#gsub
|
325
|
-
and IF::String#+. These methods create a new Rio using the string created by
|
326
|
-
forwarding the method to the String returned by Rio#to_s.
|
327
|
-
|
328
|
-
ario = rio('dirA/dirB/afile') + '-1.1.1' # rio('dirA/dirB/afile-1.1.1')
|
329
|
-
brio = ario.sub(/^dirA/, 'dirC') # rio('dirC/dirB/afile-1.1.1')
|
330
|
-
|
331
|
-
|
332
|
-
==== Creating a Rio based on its relationship to another
|
333
|
-
|
334
|
-
IF::Path#abs creates a new rio whose path is the absolute path of a Rio.
|
335
|
-
If called with an argument, it uses it as the base path, otherwise
|
336
|
-
it uses an internal base path (usually the current working directory
|
337
|
-
when it was created).
|
338
|
-
|
339
|
-
rio('/tmp').chdir do
|
340
|
-
rio('a').abs #=> rio('/tmp/a')
|
341
|
-
rio('a').abs('/usr') #=> rio('/usr/a')
|
342
|
-
end
|
343
|
-
|
344
|
-
IF::Path#rel creates a new rio with a path relative to a Rio.
|
345
|
-
|
346
|
-
rio('/tmp').chdir do
|
347
|
-
rio('/tmp/a').rel #=> rio('a')
|
348
|
-
end
|
349
|
-
rio('/tmp/b').rel('/tmp') #=> rio('b')
|
350
|
-
|
351
|
-
IF::Path#route_to and IF::Path#route_from creates a new rio with a path
|
352
|
-
representing the route to get to/from a Rio. They are based on the
|
353
|
-
methods of the same names in the ::URI class
|
354
|
-
|
355
|
-
=== Configuring a Rio
|
356
|
-
|
357
|
-
The second step in using a rio is configuring it. Note that many times
|
358
|
-
no configuration is necessary and that this is not a comprehensive
|
359
|
-
list of all of Rio's configuration methods.
|
360
|
-
|
361
|
-
Rio's configuration mehods fall into three categories.
|
362
|
-
|
363
|
-
* I/O manipulators
|
364
|
-
|
365
|
-
An I/O manipulator alters the behavior of a Rio's underlying IO
|
366
|
-
object. These affect the behaviour of I/O methods which are
|
367
|
-
forwarded directly to the underlying object as well as the grande
|
368
|
-
I/O methods.
|
369
|
-
|
370
|
-
* Grande configuration methods
|
371
|
-
|
372
|
-
The grande configuration methods affect the behaviour of Rio's
|
373
|
-
grande I/O methods
|
374
|
-
|
375
|
-
* Grande selection methods
|
376
|
-
|
377
|
-
The grande selection methods select what data is returned by Rio's
|
378
|
-
grande I/O methods
|
379
|
-
|
380
|
-
All of Rio's configuration and selection methods can be passed a
|
381
|
-
block, which will cause the Rio to behave as if IF::Grande#each had been called
|
382
|
-
with the block after the method.
|
383
|
-
|
384
|
-
==== IO manipulators
|
385
|
-
|
386
|
-
* +gzip+ a file on output, and ungzip it on input
|
387
|
-
|
388
|
-
rio('afile.gz').gzip
|
389
|
-
|
390
|
-
This causes the rio to read through a Zlib::GzipReader and to write
|
391
|
-
Zlib::GzipWriter.
|
392
|
-
|
393
|
-
* +chomp+ lines as they are read
|
394
|
-
|
395
|
-
rio('afile').chomp
|
396
|
-
|
397
|
-
This causes a Rio to call String#chomp on the the String returned by
|
398
|
-
all line oriented read operations.
|
399
|
-
|
400
|
-
==== Grande configuration methods
|
401
|
-
|
402
|
-
* +all+, +recurse+, +norecurse+
|
403
|
-
|
404
|
-
rio('adir').all
|
405
|
-
rio('adir').norecurse('CVS')
|
406
|
-
|
407
|
-
These methods instruct the Rio to also include entries in
|
408
|
-
subdirectories when iterating through directories and control which
|
409
|
-
subdirectories are included or excluded.
|
410
|
-
|
411
|
-
* +bytes+
|
412
|
-
|
413
|
-
rio('afile').bytes(1024)
|
414
|
-
|
415
|
-
This causes a Rio to read the specified number of bytes at a time as
|
416
|
-
a file is iterated through.
|
417
|
-
|
418
|
-
==== Grande selection methods
|
419
|
-
|
420
|
-
* +lines+, +skiplines+
|
421
|
-
|
422
|
-
rio('afile').lines(0..9)
|
423
|
-
rio('afile').skiplines(/^\s*#/)
|
424
|
-
|
425
|
-
Strictly speaking these are both configuration and selection
|
426
|
-
methods. They configure the Rio to iterate through an input stream
|
427
|
-
as lines. The arguments select which lines are actually returned.
|
428
|
-
Lines are included (+lines+) or excluded (+skiplines+) if they match
|
429
|
-
*any* of the arguments as follows.
|
430
|
-
|
431
|
-
If the argument is a:
|
432
|
-
+RegExp+:: the line is matched against it
|
433
|
-
+Range+:: the lineno is matched against it
|
434
|
-
+Integer+:: the lineno is matched against it as if it were a one element range
|
435
|
-
+Symbol+:: the symbol is +sent+ to the string; the line is included unless it returns false
|
436
|
-
+Proc+:: the proc is called with the line as an argument; the line is included unless it returns false
|
437
|
-
+Array+:: an array containing any of the above, all of which must match for the line to be included
|
438
|
-
|
439
|
-
* +entries+, +files+, +dirs+, +skipentries+, +skipfiles+, +skipdirs+
|
440
|
-
|
441
|
-
rio('adir').files('*.txt')
|
442
|
-
rio('adir').skipfiles(/^\./)
|
443
|
-
|
444
|
-
These methods select which entries will be returned when iterating
|
445
|
-
through directories. Entries are included (+entries+,+files+,+dirs+)
|
446
|
-
or excluded(+skipentries+,+skipfiles+,+skipdirs+) if they match *any* of
|
447
|
-
the arguments as follows.
|
448
|
-
|
449
|
-
If the argument is a:
|
450
|
-
+String+:: the arg is treated as a glob; the filname is matched against it
|
451
|
-
+RegExp+:: the filname is matched against it
|
452
|
-
+Symbol+:: the symbol is +sent+ to the entry (a Rio); the entry is included unless it returns false
|
453
|
-
+Proc+:: the proc is called with the entry (a Rio) as an argument; the entry is included unless it returns false
|
454
|
-
+Array+:: an array containing any of the above, all of which must match for the line to be included
|
455
|
-
|
456
|
-
* +records+, +rows+, +skiprecords+, +skiprows+
|
457
|
-
|
458
|
-
rio('afile').bytes(1024).records(0...10)
|
459
|
-
|
460
|
-
These select items from an input stream just as +lines+, but without
|
461
|
-
specifying lines as the input record type. They can be used to
|
462
|
-
select different record types in extension modules. The only such
|
463
|
-
module at this writing is the CSV extension. In that case +records+
|
464
|
-
causes each line of a CSV file to be parsed into an array while
|
465
|
-
+lines+ causes each line of the file to be returned normally.
|
466
|
-
|
467
|
-
=== Rio I/O
|
468
|
-
|
469
|
-
As stated above the the three steps to using a Rio are:
|
470
|
-
* Creating a Rio
|
471
|
-
* Configuring a Rio
|
472
|
-
* Doing I/O
|
473
|
-
|
474
|
-
This section describes that final step.
|
475
|
-
|
476
|
-
After creating and configuring a Rio, the file-system has not been
|
477
|
-
accessed, no socket has been opened, not so much as a test for a files
|
478
|
-
existance has been done. When an I/O method is called on a Rio, the
|
479
|
-
sequence of events required to complete that operation on the
|
480
|
-
underlying object takes place. Rio takes care of creating the
|
481
|
-
appropriate object (eg IO,Dir), opening the object with the appropriate
|
482
|
-
mode, performing the operation, closing the object if required, and
|
483
|
-
returning the results of the operation.
|
484
|
-
|
485
|
-
Rio's I/O operations can be divide into two catagories:
|
486
|
-
* Proxy operations
|
487
|
-
* Grande operations
|
488
|
-
|
489
|
-
==== Proxy operations
|
490
|
-
|
491
|
-
These are calls which are forwarded to the underlying object (eg
|
492
|
-
IO,Dir,Net::FTP), after appropriately creating and configuring that
|
493
|
-
object. The result produced by the method is returned, and the object
|
494
|
-
is closed.
|
495
|
-
|
496
|
-
In some cases the result is modified before being returned, as when a
|
497
|
-
Rio is configured with IF::GrandeStream#chomp.
|
498
|
-
|
499
|
-
In all cases, if the result returned by the underlying object, could
|
500
|
-
itself be used for further I/O operations it is returned as a Rio. For
|
501
|
-
example: where File#dirname returns a string, IF::Path#dirname returns a
|
502
|
-
Rio; where Dir#read returns a string representing a directory entry,
|
503
|
-
IF::FileOrDir#read returns a Rio.
|
504
|
-
|
505
|
-
With some noteable exceptions, most of the operations available if one
|
506
|
-
were using the underlying Ruby I/O class are available to the Rio and
|
507
|
-
will behave identically.
|
508
|
-
|
509
|
-
For things that exist on a file system:
|
510
|
-
|
511
|
-
* All the methods in FileTest are available as Rio instance
|
512
|
-
methods. For example
|
513
|
-
|
514
|
-
FileTest.file?('afile')
|
515
|
-
|
516
|
-
becomes
|
517
|
-
|
518
|
-
rio('afile').file?
|
519
|
-
|
520
|
-
* All the instance methods of +File+ except +path+ are available to a
|
521
|
-
rio without change
|
522
|
-
|
523
|
-
* Most of the class methods of +File+ are available.
|
524
|
-
|
525
|
-
* For those that take a filename as their only argument the calls
|
526
|
-
are mapped to Rio instance methods as described above for
|
527
|
-
FileTest.
|
528
|
-
|
529
|
-
* +dirname+, and +readlink+ return Rios instead of strings
|
530
|
-
|
531
|
-
* Rio has its own IF::Path#basename, IF::Path#join and IF::FileOrDir#symlink, which
|
532
|
-
provide similar functionality.
|
533
|
-
|
534
|
-
* The class methods which take multiple filenames
|
535
|
-
(+chmod+,+chown+,+lchmod+,+lchown+) are available as Rio instance
|
536
|
-
methods. For example
|
537
|
-
|
538
|
-
File.chmod(0666,'afile')
|
539
|
-
becomes
|
540
|
-
rio('afile').chmod(06660)
|
541
|
-
|
542
|
-
For I/O Streams
|
543
|
-
|
544
|
-
Most of the instance methods of IO are available, and most do the same
|
545
|
-
thing, with some interface changes. <b>The big exception to this is
|
546
|
-
the '<<' operator.</b> This is one of Rio's grande operators. While
|
547
|
-
the symantics one would use to write to an IO object would actually
|
548
|
-
accomplish the same thing with a Rio, It is a very different
|
549
|
-
operator. Read the section on grande operators. The other differences
|
550
|
-
between IO instance methods and the Rio equivelence can be summarized
|
551
|
-
as follows.
|
552
|
-
|
553
|
-
* The simple instance methods (eg +fcntl+, <tt>eof?</tt>,
|
554
|
-
<tt>tty?</tt> etc.) are forwarded and the result returned as is
|
555
|
-
|
556
|
-
* Anywhere IO returns an IO, Rio returns a Rio
|
557
|
-
|
558
|
-
* +close+ and its cousins return the Rio.
|
559
|
-
|
560
|
-
* +each_byte+ and +each_line+ are forwarded as is.
|
561
|
-
|
562
|
-
* All methods which read (read*,get*,each*) will cause the file to
|
563
|
-
closed when the end of file is reached. This behavior is
|
564
|
-
configurable, but the default is to close on eof
|
565
|
-
|
566
|
-
* The methods which write (put*,print*) are forwarded as is; put* and
|
567
|
-
print* return the Rio; write returns the value returned by IO#write;
|
568
|
-
as mentioned above '<<' is a grande operator in Rio.
|
569
|
-
|
570
|
-
For directories:
|
571
|
-
|
572
|
-
* all the instance methods of Dir are available except +each+ which is
|
573
|
-
a grande method.
|
574
|
-
|
575
|
-
* the class methods +mkdir+, +delete+, +rmdir+ are provided as
|
576
|
-
instance methods.
|
577
|
-
|
578
|
-
* +chdir+ is provided as an instance method. IF::Dir#chdir returns a Rio
|
579
|
-
and passes a Rio to a block if one is provided.
|
580
|
-
|
581
|
-
* +glob+ is provided as an instance method, but returns an array of
|
582
|
-
Rios
|
583
|
-
|
584
|
-
* +foreach+ is not supported
|
585
|
-
|
586
|
-
* +each+ and <tt>[]</tt> have similar functionality provided by Rio
|
587
|
-
|
588
|
-
|
589
|
-
For other Rios, instance methods are generally forwarded where
|
590
|
-
appropriate. For example
|
591
|
-
|
592
|
-
* Rios that refer to StringIO objects forward 'string' and 'string='
|
593
|
-
|
594
|
-
* Rios that refer to http URIs support all the Meta methods provided
|
595
|
-
by open-uri
|
596
|
-
|
597
|
-
|
598
|
-
==== Grande operators
|
599
|
-
|
600
|
-
The primary grande operator is IF::Grande#each. +each+ is used to iterate
|
601
|
-
through Rios. When applied to a file it iterates through records in
|
602
|
-
the file. When applied to a directory it iterates through the entries
|
603
|
-
in the directory. Its behavior is modified by configuring the Rio
|
604
|
-
prior to calling it using the configuration methods discussed
|
605
|
-
above. Since iterating through things is ubiquitous in ruby, it is
|
606
|
-
implied by the presence of a block after any of the grande
|
607
|
-
configuration methods and many times does not need to be call
|
608
|
-
explicitly. For example:
|
609
|
-
|
610
|
-
# iterate through chomped ruby comment lines
|
611
|
-
rio('afile.rb').chomp.lines(/^\s*#/) { |line| ... }
|
612
|
-
|
613
|
-
# iterate through all .rb files in 'adir' and its subdirectories
|
614
|
-
rio('adir').all.files('*.rb') { |f| ... }
|
615
|
-
|
616
|
-
Because a Rio is an Enumerable, it supports +to_a+, which is the basis
|
617
|
-
for the grande subscript operator. IF::Grande#[] with no arguments simply
|
618
|
-
calls to_a. With arguments it behaves as if those arguments had been
|
619
|
-
passed to the most recently called of the grande selection methods
|
620
|
-
listed above, and then calls to_a. For example to get the first ten
|
621
|
-
lines of a file into an array with lines chomped
|
622
|
-
|
623
|
-
rio('afile').chomp.lines(0...10).to_a
|
624
|
-
|
625
|
-
can be written as
|
626
|
-
|
627
|
-
rio('afile.gz').chomp.lines[0...10]
|
628
|
-
|
629
|
-
or, to create an array of all the .c files in a directory, one could
|
630
|
-
write
|
631
|
-
|
632
|
-
rio('adir').files['*.c']
|
633
|
-
|
634
|
-
The other grande operators are its copy operators. They are:
|
635
|
-
|
636
|
-
* <tt><</tt> (copy-from)
|
637
|
-
|
638
|
-
* <tt><<</tt> (append-from)
|
639
|
-
|
640
|
-
* <tt>></tt> (copy-to)
|
641
|
-
|
642
|
-
* <tt>>></tt> (append-to)
|
643
|
-
|
644
|
-
The only difference between the 'copy' and 'append' versions is how
|
645
|
-
they deal with an unopened resource. In the former the open it with
|
646
|
-
mode 'w' and in the latter, mode 'a'. Beyond that, their behavior can
|
647
|
-
be summarized as:
|
648
|
-
|
649
|
-
source.each do |entry|
|
650
|
-
destination << entry
|
651
|
-
end
|
652
|
-
|
653
|
-
Since they are based on the +each+ operator, all of the selection and
|
654
|
-
configuration options are available. And the right-hand-side argument
|
655
|
-
of the operators are not restricted to Rios -- Strings and Arrays are
|
656
|
-
also supported.
|
657
|
-
|
658
|
-
For example:
|
659
|
-
|
660
|
-
rio('afile') > astring # copy a file into a string
|
661
|
-
|
662
|
-
rio('afile').chomp > anarray # copy the chomped lines of afile into an array
|
663
|
-
|
664
|
-
rio('afile.gz').gzip.lines(0...100) > rio('bfile') # copy 100 lines from a gzipped file into another file
|
665
|
-
|
666
|
-
rio(?-) < rio('http://rubydoc.org/') # copy a web page to stdout
|
667
|
-
|
668
|
-
rio('bdir') < rio('adir') # copy an entire directory structure
|
669
|
-
|
670
|
-
rio('adir').dirs.files('README') > rio('bdir') # same thing, but only README files
|
671
|
-
|
672
|
-
rio(?-,'ps -a').skiplines(0,/ps$/) > anarray # copy the output of th ps command into an array, skippying
|
673
|
-
# the header line and the ps command entry
|
674
|
-
|
675
|
-
=== Renaming and Moving
|
676
|
-
|
677
|
-
Rio provides two methods for directly renaming objects on the
|
678
|
-
filesystem: IF::FileOrDir#rename and IF::FileOrDir#rename!.
|
679
|
-
Both of these use File#rename.
|
680
|
-
The difference between them is the returned Rio.
|
681
|
-
IF::FileOrDir#rename leaves the path of the Rio unchanged,
|
682
|
-
while IF::FileOrDir#rename! changes the path of the Rio to refer
|
683
|
-
to the renamed path.
|
684
|
-
|
685
|
-
ario = rio('a')
|
686
|
-
ario.rename('b') # file 'a' has been renamed to 'b' but 'ario' => rio('a')
|
687
|
-
ario.rename!('b') # file 'a' has been renamed to 'b' and 'ario' => rio('b')
|
688
|
-
|
689
|
-
Rio also has a +rename+ mode, which causes the path manipulation
|
690
|
-
methods IF::Path#dirname=, IF::Path#filename=, IF::Path#basename= and
|
691
|
-
IF::Path#extname= to rename an object on the filesystem when they are
|
692
|
-
used to change a Rio's path. A Rio is put in +rename+ mode by calling
|
693
|
-
IF::FileOrDir#rename with no arguments.
|
694
|
-
|
695
|
-
rio('adir/afile.txt').rename.filename = 'bfile.rb' # adir/afile.txt => adir/bfile.rb
|
696
|
-
rio('adir/afile.txt').rename.basename = 'bfile' # adir/afile.txt => adir/bfile.txt
|
697
|
-
rio('adir/afile.txt').rename.extname = '.rb' # adir/afile.txt => adir/afile.rb
|
698
|
-
rio('adir/afile.txt').rename.dirname = 'b/c' # adir/afile.txt => b/c/afile.txt
|
699
|
-
|
700
|
-
When +rename+ mode is set for a directory Rio, it is automatically set
|
701
|
-
in the Rios created when iterating through that directory.
|
702
|
-
|
703
|
-
rio('adir').rename.files('*.htm') do |frio|
|
704
|
-
frio.extname = '.html' #=> changes the rio and renames the file
|
705
|
-
end
|
706
|
-
|
707
|
-
=== Deleting
|
708
|
-
|
709
|
-
The Rio methods for deleting filesystem objects are IF::File#rm, IF::Dir#rmdir,
|
710
|
-
IF::Dir#rmtree, IF::Grande#delete, and IF::Grande#delete!. +rm+, +rmdir+ and +rmtree+
|
711
|
-
are passed the like named methods in the FileUtils module. IF::Grande#delete
|
712
|
-
calls +rmdir+ for directories and +rm+ for anything else, while
|
713
|
-
IF::Grande#delete! calls IF::Dir#rmtree for directories.
|
714
|
-
|
715
|
-
* To delete something only if it is not a directory use IF::File#rm
|
716
|
-
* To delete an empty directory use IF::Dir#rmdir
|
717
|
-
* To delete an entire directory tree use IF::Dir#rmtree
|
718
|
-
* To delete anything except a populated directory use IF::Grande#delete
|
719
|
-
* To delete anything use IF::Grande#delete!
|
720
|
-
|
721
|
-
It is not an error to call any of the deleting methods on something
|
722
|
-
that does not exist. Rio provides IF::Test#exist? and IF::Test#symlink? to check
|
723
|
-
if something exists (<tt>exist?</tt> returns false for symlinks to
|
724
|
-
non-existant object even though the symlink itself exists). The
|
725
|
-
deleting methods' purpose is to make things not exist, so calling one
|
726
|
-
of them on something that already does not exist is considered a
|
727
|
-
success.
|
728
|
-
|
729
|
-
To create a clean copy of a directory whether or not anything with
|
730
|
-
that name exists one might do this
|
731
|
-
|
732
|
-
rio('adir').delete!.mkpath.chdir do
|
733
|
-
# do something in adir
|
734
|
-
end
|
735
|
-
|
736
|
-
---
|
737
|
-
|
738
|
-
== Miscellany
|
739
|
-
|
740
|
-
|
741
|
-
==== Using Symbolic Links
|
742
|
-
|
743
|
-
To create a symbolic link (symlink) to the file-system entry refered
|
744
|
-
to by a Rio, use IF::FileOrDir#symlink. IF::FileOrDir#symlink differs from File#symlink
|
745
|
-
in that it calculates the path from the symlink location to the Rio's
|
746
|
-
position.
|
747
|
-
|
748
|
-
File#symlink('adir/afile','adir/alink')
|
749
|
-
|
750
|
-
creates a symlink in the directory 'adir' named 'alink' which
|
751
|
-
references 'adir/afile'. From the perspective of 'alink', 'adir/afile'
|
752
|
-
does not exist. While:
|
753
|
-
|
754
|
-
rio('adir/afile').symlink('adir/alink')
|
755
|
-
|
756
|
-
creates a symlink in the directory 'adir' named 'alink' which
|
757
|
-
references 'afile'. This is the route to 'adir/afile' from the
|
758
|
-
perspective of 'adir/alink'.
|
759
|
-
|
760
|
-
Note that the return value from +symlink+ is the calling Rio and not a
|
761
|
-
Rio refering to the symlink. This is done for consistency with the
|
762
|
-
rest of Rio.
|
763
|
-
|
764
|
-
IF::Test#symlink? can be used to test if a file-system object is a
|
765
|
-
symlink. A Rio is extended with IF::FileOrDir#readlink, and
|
766
|
-
IF::Test#lstat only if IF::Test#symlink? returns true. So for
|
767
|
-
non-symlinks, these will raise a NoMethodError. These are both passed
|
768
|
-
to their counterparts in File. IF::FileOrDir#readlink returns a Rio
|
769
|
-
refering to the result of File#readlink.
|
770
|
-
|
771
|
-
|
772
|
-
==== Using A Rio as an IO (or File or Dir)
|
773
|
-
|
774
|
-
Rio supports so much of IO's interface that one might be tempted to
|
775
|
-
pass it to a method that expects an IO. While Rio is not and is not
|
776
|
-
intended to be a stand in for IO, this can work. It requires
|
777
|
-
knowledge of every IO method that will be called, under any
|
778
|
-
circumstances.
|
779
|
-
|
780
|
-
Even in cases where Rio supports the required IO interface, A Rio
|
781
|
-
feature that seems to cause the most incompatibility, is its automatic
|
782
|
-
closing of files. To turn off all of Rio's automatic closing use
|
783
|
-
IF::GrandeStream#noautoclose.
|
784
|
-
|
785
|
-
For example:
|
786
|
-
require 'yaml'
|
787
|
-
yrio = rio('ran.yaml').delete!.noautoclose
|
788
|
-
YAML.dump( ['badger', 'elephant', 'tiger'], yrio )
|
789
|
-
obj = YAML::load( yrio ) #=> ["badger", "tiger", "elephant"]
|
790
|
-
|
791
|
-
|
792
|
-
==== Automatically Closing Files
|
793
|
-
|
794
|
-
Rio closes files automatically in three instances.
|
795
|
-
|
796
|
-
When reading from an IO it is closed when the end of file is
|
797
|
-
reached. While this is a reasonable thing to do in many cases,
|
798
|
-
sometimes this is not desired. To turn Rio's automatic closing on end
|
799
|
-
of file use IF::GrandeStream#nocloseoneof (it can be turned back on via
|
800
|
-
IF::GrandeStream#closeoneof)
|
801
|
-
|
802
|
-
ario = rio('afile').nocloseoneof
|
803
|
-
lines = ario[]
|
804
|
-
ario.closed? #=> false
|
805
|
-
|
806
|
-
Closing on end-of-file is necessary for many of Rio's one-liners, but
|
807
|
-
has an implication that may be surprising at first. A Rio starts life
|
808
|
-
as a path, not much more than a string. When one of its read methods
|
809
|
-
is called it becomes an input stream. When the stream is closed, it
|
810
|
-
becomes a path again. This means that when reading from a Rio, the
|
811
|
-
end-of-file condition is seen only once before it becomes a path
|
812
|
-
again, and will be reopened if another read operation is attempted.
|
813
|
-
|
814
|
-
Another time a Rio will be closed atomatically is when writing to it
|
815
|
-
with one of the copy operators (<tt><, <<, >, >></tt>). This behavior
|
816
|
-
can be turned off with IF::GrandeStream#nocloseoncopy.
|
817
|
-
|
818
|
-
To turn off both of thes types of automatic closing use
|
819
|
-
IF::GrandeStream#noautoclose.
|
820
|
-
|
821
|
-
The third instance when Rio will close a file automatically is when a
|
822
|
-
file opened for one type of access receives a method which that access
|
823
|
-
mode does not support. So, the code
|
824
|
-
rio('afile').puts("Hello World").gets
|
825
|
-
will open the file for write access when the +puts+
|
826
|
-
method is received. When +gets+ is called the file is closed and
|
827
|
-
reopened with read access.
|
828
|
-
|
829
|
-
==== Explicitly Closing Files
|
830
|
-
|
831
|
-
Rio can not determine when the client is finished writing to it, as it
|
832
|
-
does using +eof+ on read. It is the author's understanding that Ruby
|
833
|
-
does not support a mechanism to have code run when there are no more
|
834
|
-
references to it -- that finalizers are not necessarily run immediatly
|
835
|
-
upon an object's reference count reaching 0. If this understanding is
|
836
|
-
incorrect, some of Rio's extranious ways of closing a file may be
|
837
|
-
rethought.
|
838
|
-
|
839
|
-
That being said, Rio support several ways to explicitly close a
|
840
|
-
file. IF::RubyIO#close will close any open Rio.
|
841
|
-
The output methods
|
842
|
-
IF::RubyIO#puts!, IF::RubyIO#putc!, IF::RubyIO#printf!, IF::RubyIO#print!, and IF::RubyIO#write!
|
843
|
-
behave as if their
|
844
|
-
counterparts without the exclamation point had been called and then
|
845
|
-
call IF::RubyIO#close or IF::RubyIO#close_write if the underlying IO object is
|
846
|
-
opened for duplex access.
|
847
|
-
|
848
|
-
|
849
|
-
==== Open mode selection
|
850
|
-
|
851
|
-
A Rio is typically not explicitly opened. It opens a file
|
852
|
-
automatically when an input or output methed is called. For output
|
853
|
-
methods Rio opens a file with mode 'w', and otherwise opens a file
|
854
|
-
with mode 'r'. This behavior can be modified using the tersely named
|
855
|
-
methods IF::GrandeStream#a, IF::GrandeStream#a!, IF::GrandeStream#r, IF::GrandeStream#r!, IF::GrandeStream#w, and IF::GrandeStream#w!, which cause
|
856
|
-
the Rio to use modes 'a','a+','r','r+','w',and 'w+' respectively.
|
857
26
|
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
rio('
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
27
|
+
#
|
28
|
+
# = Rio - Ruby I/O Facilitator
|
29
|
+
#
|
30
|
+
# fa-cil-i-tate: To make easy or easier.
|
31
|
+
#
|
32
|
+
# Rio is a facade for most of the standard ruby classes that deal with I/O;
|
33
|
+
# providing a simple, intuitive, succinct interface to the functionality
|
34
|
+
# provided by IO, File, Dir, Pathname, FileUtils, Tempfile, StringIO, OpenURI
|
35
|
+
# and others. Rio also provides an application level interface which allows many
|
36
|
+
# common I/O idioms to be expressed succinctly.
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# Rio functionality can be broadly broken into three categories
|
40
|
+
# * path manipulation
|
41
|
+
# * file system access
|
42
|
+
# * stream manipulation
|
43
|
+
#
|
44
|
+
# Which methods are available to a given Rio, depends on the underlying
|
45
|
+
# object.
|
46
|
+
#
|
47
|
+
# A Rio generally does not need to be opened or have its mode specified.
|
48
|
+
# Most of Rio's methods simply configure it. When an actual IO
|
49
|
+
# operation is specified, Rio determines how to open it based on the
|
50
|
+
# object it is opening, the operation it is performing, and the options
|
51
|
+
# specified.
|
52
|
+
#
|
53
|
+
# Rio configuration methods return the Rio for easy chaining and regard
|
54
|
+
# the presence of a block as an implied +each+.
|
55
|
+
#
|
56
|
+
# == Using a Rio
|
57
|
+
#
|
58
|
+
# Using a Rio can be described as having 3 steps:
|
59
|
+
# * Creating a Rio
|
60
|
+
# * Configuring a Rio
|
61
|
+
# * Rio I/O
|
62
|
+
#
|
63
|
+
# === Creating a Rio
|
64
|
+
#
|
65
|
+
# Rio extends Kernel with one function +rio+, its constructor. This
|
66
|
+
# function is overloaded to create any type of Rio. +rio+ looks at the
|
67
|
+
# class and sometimes the value of its first argument to create an
|
68
|
+
# internal representation of the resource specified, additional
|
69
|
+
# arguments are used as needed by the resource type. The rio constructor
|
70
|
+
# does not initiate any io, it does not check for a resources existance
|
71
|
+
# or type. It neither knows nor cares what can be done with this Rio.
|
72
|
+
# Using methods like <tt>respond_to?</tt> are meaningless at best and usually
|
73
|
+
# misleading.
|
74
|
+
#
|
75
|
+
# For purposes of discussion, we divide Rios into two catagories, those
|
76
|
+
# that have a path and those that don't.
|
77
|
+
#
|
78
|
+
# ==== Creating a Rio that has a path
|
79
|
+
#
|
80
|
+
# To create a Rio that has a path the arguments to +rio+ may be:
|
81
|
+
#
|
82
|
+
# * a string representing the entire path. The separator used for Rios
|
83
|
+
# is as specified in RFC1738 ('/').
|
84
|
+
#
|
85
|
+
# rio('adir/afile')
|
86
|
+
#
|
87
|
+
# * a string representing a fully qualified +file+ URI as per RFC1738
|
88
|
+
#
|
89
|
+
# rio('file:///atopleveldir/adir/afile')
|
90
|
+
#
|
91
|
+
# * a +URI+ object representing a +file+ or generic +URI+
|
92
|
+
#
|
93
|
+
# rio(URI('adir/afile'))
|
94
|
+
#
|
95
|
+
# * the components of a path as separate arguments
|
96
|
+
#
|
97
|
+
# rio('adir','afile')
|
98
|
+
#
|
99
|
+
# * the components of a path as an array
|
100
|
+
#
|
101
|
+
# rio(%w/adir afile/)
|
102
|
+
#
|
103
|
+
# * another Rio
|
104
|
+
#
|
105
|
+
# another_rio = rio('adir/afile')
|
106
|
+
# rio(another_rio)
|
107
|
+
#
|
108
|
+
# * any object whose +to_s+ method returns one of the above
|
109
|
+
#
|
110
|
+
# rio(Pathname.new('apath'))
|
111
|
+
#
|
112
|
+
# * any combination of the above either as separate arguments or as
|
113
|
+
# elements of an array,
|
114
|
+
#
|
115
|
+
# another_rio = rio('dir1/dir2')
|
116
|
+
# auri = URI('dir4/dir5)
|
117
|
+
# rio(another_rio,'dir3',auri,'dir6/dir7')
|
118
|
+
#
|
119
|
+
# ===== Creating a Rio that refers to a web page
|
120
|
+
#
|
121
|
+
# To create a Rio that refers to a web page the arguments to +rio+ may
|
122
|
+
# be:
|
123
|
+
#
|
124
|
+
# * a string representing a fully qualified +http+ URI
|
125
|
+
#
|
126
|
+
# rio('http://ruby-doc.org/index.html')
|
127
|
+
#
|
128
|
+
# * a +URI+ object representing a +http+ +URI+
|
129
|
+
#
|
130
|
+
# rio(URI('http://ruby-doc.org/index.html'))
|
131
|
+
#
|
132
|
+
# * either of the above with additional path elements
|
133
|
+
#
|
134
|
+
# rio('http://www.ruby-doc.org/','core','classes/Object.html')
|
135
|
+
#
|
136
|
+
#
|
137
|
+
# ===== Creating a Rio that refers to a file or directory on a FTP server
|
138
|
+
#
|
139
|
+
# To create a Rio that refers to a file on a FTP server the arguments to
|
140
|
+
# +rio+ may be:
|
141
|
+
#
|
142
|
+
# * a string representing a fully qualified +ftp+ URI
|
143
|
+
#
|
144
|
+
# rio('ftp://user:password@ftp.example.com/afile.tar.gz')
|
145
|
+
#
|
146
|
+
# * a +URI+ object representing a +ftp+ +URI+
|
147
|
+
#
|
148
|
+
# rio(URI('ftp://ftp.example.com/afile.tar.gz'))
|
149
|
+
#
|
150
|
+
# * either of the above with additional path elements
|
151
|
+
#
|
152
|
+
# rio('ftp://ftp.gnu.org/pub/gnu','emacs','windows','README')
|
153
|
+
#
|
154
|
+
# ==== Creating Rios that do not have a path
|
155
|
+
#
|
156
|
+
# To create a Rio without a path, the first argument to +rio+ is usually
|
157
|
+
# a single character.
|
158
|
+
#
|
159
|
+
# ===== Creating a Rio that refers to a clone of your programs stdin or stdout.
|
160
|
+
#
|
161
|
+
# <tt>rio(?-)</tt> (mnemonic: '-' is used by some Unix programs to
|
162
|
+
# specify stdin or stdout in place of a file)
|
163
|
+
#
|
164
|
+
# Just as a Rio that refers to a file, does not know whether that file
|
165
|
+
# will be opened for reading or writing until an io operation is
|
166
|
+
# specified, a <tt>stdio:</tt> Rio does not know whether it will connect
|
167
|
+
# to stdin or stdout until an I/O operation is specified.
|
168
|
+
#
|
169
|
+
# ===== Creating a Rio that refers to a clone of your programs stderr.
|
170
|
+
#
|
171
|
+
# <tt>rio(?=)</tt> (mnemonic: '-' refers to fileno 1, so '=' refers to
|
172
|
+
# fileno 2)
|
173
|
+
#
|
174
|
+
# ===== Creating a Rio that refers to an arbitrary IO object.
|
175
|
+
#
|
176
|
+
# an_io = ::File.new('afile')
|
177
|
+
# rio(an_io)
|
178
|
+
#
|
179
|
+
# ===== Creating a Rio that refers to a file descriptor
|
180
|
+
#
|
181
|
+
# <tt>rio(?#,fd)</tt> (mnemonic: a file descriptor is a number '#' )
|
182
|
+
#
|
183
|
+
# an_io = ::File.new('afile')
|
184
|
+
# rio(an_io)
|
185
|
+
#
|
186
|
+
# ===== Creating a Rio that refers to a StringIO object
|
187
|
+
#
|
188
|
+
# <tt>rio(?")</tt> (mnemonic: '"' surrounds strings)
|
189
|
+
# * create a Rio that refers to its own string
|
190
|
+
# rio(?")
|
191
|
+
# * create a Rio that refers to a string of your choosing
|
192
|
+
# astring = ""
|
193
|
+
# rio(?",astring)
|
194
|
+
#
|
195
|
+
# ===== Creating a Rio that refers to a Temporary object
|
196
|
+
#
|
197
|
+
# <tt>rio(??)</tt> (mnemonic: '?' you don't know its name)
|
198
|
+
#
|
199
|
+
# To create a temporary object that will become a file
|
200
|
+
# or a directory, depending on how you use it:
|
201
|
+
# rio(??)
|
202
|
+
# rio(??,basename='rio',tmpdir=Dir::tmpdir)
|
203
|
+
#
|
204
|
+
# To force it to become a directory:
|
205
|
+
# rio(??).mkdir
|
206
|
+
# or
|
207
|
+
# rio(??).chdir
|
208
|
+
#
|
209
|
+
#
|
210
|
+
#
|
211
|
+
# ===== Creating a Rio that refers to an arbitrary TCPSocket
|
212
|
+
#
|
213
|
+
# rio('tcp:',hostname,port)
|
214
|
+
# or
|
215
|
+
# rio('tcp://hostname:port')
|
216
|
+
#
|
217
|
+
# ===== Creating a Rio that runs an external program and connects to its stdin and stdout
|
218
|
+
#
|
219
|
+
# <tt>rio(?-,cmd)</tt> (mnemonic: '-' is used by some Unix programs to
|
220
|
+
# specify stdin or stdout in place of a file)
|
221
|
+
#
|
222
|
+
# or
|
223
|
+
#
|
224
|
+
# <tt>rio(?`,cmd)</tt> (mnemonic: '`' (backtick) runs an external
|
225
|
+
# program in ruby)
|
226
|
+
#
|
227
|
+
# This is Rio's interface to IO#popen
|
228
|
+
#
|
229
|
+
# === Path Manipulation
|
230
|
+
#
|
231
|
+
# Rio's path manipulation methods are for the most part simply forwarded
|
232
|
+
# to the File or URI classes with the return values converted to a Rio.
|
233
|
+
#
|
234
|
+
# ==== Creating a Rio from a Rio's component parts.
|
235
|
+
#
|
236
|
+
# The Rio methods for creating a Rio from a Rio's component parts are
|
237
|
+
# {#dirname}[rdoc-ref:IF::Path#dirname], {#filename}[rdoc-ref:IF::Path#filename], {#basename}[rdoc-ref:IF::Path#basename], and {#extname}[rdoc-ref:IF::Path#extname]. The
|
238
|
+
# behavior of {#basename}[rdoc-ref:IF::Path#basename] depends on the setting of the +ext+
|
239
|
+
# configuration variable and is different from its counterpart in the
|
240
|
+
# File class. The default value of the +ext+ configuration variable is
|
241
|
+
# the string returned File#extname. The +ext+ configuration variable can
|
242
|
+
# be changed using {#ext}[rdoc-ref:IF::Path#ext] and {#noext}[rdoc-ref:IF::Path#noext] and can be queried using
|
243
|
+
# {#ext?}[rdoc-ref:IF::Path#ext?]. This value is used by calls to {#basename}[rdoc-ref:IF::Path#basename].
|
244
|
+
#
|
245
|
+
# {#filename}[rdoc-ref:IF::Path#filename] returns the last component of a path, and is basically
|
246
|
+
# the same as +basename+ without consideration of an extension.
|
247
|
+
#
|
248
|
+
# rio('afile.txt').basename #=> rio('afile')
|
249
|
+
# rio('afile.txt').filename #=> rio('afile.txt')
|
250
|
+
#
|
251
|
+
# ario = rio('afile.tar.gz')
|
252
|
+
# ario.basename #=> rio('afile.tar')
|
253
|
+
# ario.ext? #=> ".gz"
|
254
|
+
# ario.ext('.tar.gz').basename #=> rio('afile')
|
255
|
+
# ario.ext? #=> ".tar.gz"
|
256
|
+
#
|
257
|
+
# ==== Changing a path's component parts.
|
258
|
+
#
|
259
|
+
# Rio also provides methods for changing the component parts of its
|
260
|
+
# path. They are {#dirname=}[rdoc-ref:IF::Path#dirname=], {#filename=}[rdoc-ref:IF::Path#filename=], {#basename=}[rdoc-ref:IF::Path#basename=], and
|
261
|
+
# {#extname=}[rdoc-ref:IF::Path#extname=]. These methods replace the part extracted as described
|
262
|
+
# above with their argument.
|
263
|
+
#
|
264
|
+
# ario = rio('dirA/dirB/afile.rb')
|
265
|
+
# ario.dirname = 'dirC' # rio('dirC/afile.rb')
|
266
|
+
# ario.basename = 'bfile' # rio('dirC/bfile.rb')
|
267
|
+
# ario.extname = '.txt' # rio('dirC/bfile.txt')
|
268
|
+
# ario.filename = 'cfile.rb' # rio('dirC/cfile.rb')
|
269
|
+
#
|
270
|
+
# Rio also has a +rename+ mode which causes each of these to rename the
|
271
|
+
# actual file system object as well as changing the Rio. This is
|
272
|
+
# discussed in the section on Renaming and Moving.
|
273
|
+
#
|
274
|
+
# ==== Splitting a Rio
|
275
|
+
#
|
276
|
+
# {#split}[rdoc-ref:IF::Grande#split] (or {#splitpath}[rdoc-ref:IF::Path#splitpath]) returns an array of Rios, one
|
277
|
+
# for each path element. (Note that this behavior differs from File#split.)
|
278
|
+
#
|
279
|
+
# rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
|
280
|
+
#
|
281
|
+
# The array returned is extended with a +to_rio+ method, which will put
|
282
|
+
# the parts back together again.
|
283
|
+
#
|
284
|
+
# ary = rio('a/b/c').split #=> [rio('a'),rio('b'),rio('c')]
|
285
|
+
# ary.to_rio #=> rio('a/b/c')
|
286
|
+
#
|
287
|
+
# ==== Creating a Rio by specifying the individual parts of its path
|
288
|
+
#
|
289
|
+
# The first way to create a Rio by specifying its parts is to use the
|
290
|
+
# Rio constructor Rio#rio. Since a Rio is among the arguments the
|
291
|
+
# constructor will take, the constructor can be used.
|
292
|
+
#
|
293
|
+
# ario = rio('adir')
|
294
|
+
# rio(ario,'b') #=> rio('adir/b')
|
295
|
+
#
|
296
|
+
# {#join}[rdoc-ref:IF::Path#join] and {#/}[rdoc-ref:IF::Path#/] do the same thing, but the operator version
|
297
|
+
# <tt>/</tt> can take only one argument.
|
298
|
+
#
|
299
|
+
# a = rio('a')
|
300
|
+
# b = rio('b')
|
301
|
+
# c = a.join(b) #=> rio('a/b')
|
302
|
+
# c = a/b #=> rio('a/b')
|
303
|
+
#
|
304
|
+
# The arguments to {#join}[rdoc-ref:IF::Path#join] and {#/}[rdoc-ref:IF::Path#/] do not need to be Rios, of course
|
305
|
+
# ario = rio('adir')
|
306
|
+
# ario/'afile.rb' #=> rio('adir/afile.rb')
|
307
|
+
# ario.join('b','c','d') #=> rio('adir/b/c/d')
|
308
|
+
# ario/'b'/'c'/'d' #=> rio('adir/b/c/d')
|
309
|
+
# ario /= 'e' #=> rio('adir/b/c/d/e')
|
310
|
+
#
|
311
|
+
# ==== Manipulating a Rio path by treating it as a string.
|
312
|
+
#
|
313
|
+
# The Rio methods which treat a Rio as a string are {#sub}[rdoc-ref:IF::String#sub], {#gsub}[rdoc-ref:IF::String#gsub]
|
314
|
+
# and {#+}[rdoc-ref:IF::String#+]. These methods create a new Rio using the string created by
|
315
|
+
# forwarding the method to the String returned by Rio#to_s.
|
316
|
+
#
|
317
|
+
# ario = rio('dirA/dirB/afile') + '-1.1.1' # rio('dirA/dirB/afile-1.1.1')
|
318
|
+
# brio = ario.sub(/^dirA/, 'dirC') # rio('dirC/dirB/afile-1.1.1')
|
319
|
+
#
|
320
|
+
#
|
321
|
+
# ==== Creating a Rio based on its relationship to another
|
322
|
+
#
|
323
|
+
# {#abs}[rdoc-ref:IF::Path#abs] creates a new rio whose path is the absolute path of a Rio.
|
324
|
+
# If called with an argument, it uses it as the base path, otherwise
|
325
|
+
# it uses an internal base path (usually the current working directory
|
326
|
+
# when it was created).
|
327
|
+
#
|
328
|
+
# rio('/tmp').chdir do
|
329
|
+
# rio('a').abs #=> rio('/tmp/a')
|
330
|
+
# rio('a').abs('/usr') #=> rio('/usr/a')
|
331
|
+
# end
|
332
|
+
#
|
333
|
+
# {#rel}[rdoc-ref:IF::Path#rel] creates a new rio with a path relative to a Rio.
|
334
|
+
#
|
335
|
+
# rio('/tmp').chdir do
|
336
|
+
# rio('/tmp/a').rel #=> rio('a')
|
337
|
+
# end
|
338
|
+
# rio('/tmp/b').rel('/tmp') #=> rio('b')
|
339
|
+
#
|
340
|
+
# {#route}[rdoc-ref:IF::Path#route]_to and {#route}[rdoc-ref:IF::Path#route]_from creates a new rio with a path
|
341
|
+
# representing the route to get to/from a Rio. They are based on the
|
342
|
+
# methods of the same names in the ::URI class
|
343
|
+
#
|
344
|
+
# === Configuring a Rio
|
345
|
+
#
|
346
|
+
# The second step in using a rio is configuring it. Note that many times
|
347
|
+
# no configuration is necessary and that this is not a comprehensive
|
348
|
+
# list of all of Rio's configuration methods.
|
349
|
+
#
|
350
|
+
# Rio's configuration mehods fall into three categories.
|
351
|
+
#
|
352
|
+
# * I/O manipulators
|
353
|
+
#
|
354
|
+
# An I/O manipulator alters the behavior of a Rio's underlying IO
|
355
|
+
# object. These affect the behaviour of I/O methods which are
|
356
|
+
# forwarded directly to the underlying object as well as the grande
|
357
|
+
# I/O methods.
|
358
|
+
#
|
359
|
+
# * Grande configuration methods
|
360
|
+
#
|
361
|
+
# The grande configuration methods affect the behaviour of Rio's
|
362
|
+
# grande I/O methods
|
363
|
+
#
|
364
|
+
# * Grande selection methods
|
365
|
+
#
|
366
|
+
# The grande selection methods select what data is returned by Rio's
|
367
|
+
# grande I/O methods
|
368
|
+
#
|
369
|
+
# All of Rio's configuration and selection methods can be passed a
|
370
|
+
# block, which will cause the Rio to behave as if {#each}[rdoc-ref:IF::Grande#each] had been called
|
371
|
+
# with the block after the method.
|
372
|
+
#
|
373
|
+
# ==== IO manipulators
|
374
|
+
#
|
375
|
+
# * +gzip+ a file on output, and ungzip it on input
|
376
|
+
#
|
377
|
+
# rio('afile.gz').gzip
|
378
|
+
#
|
379
|
+
# This causes the rio to read through a Zlib::GzipReader and to write
|
380
|
+
# Zlib::GzipWriter.
|
381
|
+
#
|
382
|
+
# * +chomp+ lines as they are read
|
383
|
+
#
|
384
|
+
# rio('afile').chomp
|
385
|
+
#
|
386
|
+
# This causes a Rio to call String#chomp on the the String returned by
|
387
|
+
# all line oriented read operations.
|
388
|
+
#
|
389
|
+
# ==== Grande configuration methods
|
390
|
+
#
|
391
|
+
# * +all+, +recurse+, +norecurse+
|
392
|
+
#
|
393
|
+
# rio('adir').all
|
394
|
+
# rio('adir').norecurse('CVS')
|
395
|
+
#
|
396
|
+
# These methods instruct the Rio to also include entries in
|
397
|
+
# subdirectories when iterating through directories and control which
|
398
|
+
# subdirectories are included or excluded.
|
399
|
+
#
|
400
|
+
# * +bytes+
|
401
|
+
#
|
402
|
+
# rio('afile').bytes(1024)
|
403
|
+
#
|
404
|
+
# This causes a Rio to read the specified number of bytes at a time as
|
405
|
+
# a file is iterated through.
|
406
|
+
#
|
407
|
+
# ==== Grande selection methods
|
408
|
+
#
|
409
|
+
# * +lines+, +skiplines+
|
410
|
+
#
|
411
|
+
# rio('afile').lines(0..9)
|
412
|
+
# rio('afile').skiplines(/^\s*#/)
|
413
|
+
#
|
414
|
+
# Strictly speaking these are both configuration and selection
|
415
|
+
# methods. They configure the Rio to iterate through an input stream
|
416
|
+
# as lines. The arguments select which lines are actually returned.
|
417
|
+
# Lines are included (+lines+) or excluded (+skiplines+) if they match
|
418
|
+
# *any* of the arguments as follows.
|
419
|
+
#
|
420
|
+
# If the argument is a:
|
421
|
+
# +RegExp+:: the line is matched against it
|
422
|
+
# +Range+:: the lineno is matched against it
|
423
|
+
# +Integer+:: the lineno is matched against it as if it were a one element range
|
424
|
+
# +Symbol+:: the symbol is +sent+ to the string; the line is included unless it returns false
|
425
|
+
# +Proc+:: the proc is called with the line as an argument; the line is included unless it returns false
|
426
|
+
# +Array+:: an array containing any of the above, all of which must match for the line to be included
|
427
|
+
#
|
428
|
+
# * +entries+, +files+, +dirs+, +skipentries+, +skipfiles+, +skipdirs+
|
429
|
+
#
|
430
|
+
# rio('adir').files('*.txt')
|
431
|
+
# rio('adir').skipfiles(/^\./)
|
432
|
+
#
|
433
|
+
# These methods select which entries will be returned when iterating
|
434
|
+
# through directories. Entries are included (+entries+,+files+,+dirs+)
|
435
|
+
# or excluded(+skipentries+,+skipfiles+,+skipdirs+) if they match *any* of
|
436
|
+
# the arguments as follows.
|
437
|
+
#
|
438
|
+
# If the argument is a:
|
439
|
+
# +String+:: the arg is treated as a glob; the filname is matched against it
|
440
|
+
# +RegExp+:: the filname is matched against it
|
441
|
+
# +Symbol+:: the symbol is +sent+ to the entry (a Rio); the entry is included unless it returns false
|
442
|
+
# +Proc+:: the proc is called with the entry (a Rio) as an argument; the entry is included unless it returns false
|
443
|
+
# +Array+:: an array containing any of the above, all of which must match for the line to be included
|
444
|
+
#
|
445
|
+
# * +records+, +rows+, +skiprecords+, +skiprows+
|
446
|
+
#
|
447
|
+
# rio('afile').bytes(1024).records(0...10)
|
448
|
+
#
|
449
|
+
# These select items from an input stream just as +lines+, but without
|
450
|
+
# specifying lines as the input record type. They can be used to
|
451
|
+
# select different record types in extension modules. The only such
|
452
|
+
# module at this writing is the CSV extension. In that case +records+
|
453
|
+
# causes each line of a CSV file to be parsed into an array while
|
454
|
+
# +lines+ causes each line of the file to be returned normally.
|
455
|
+
#
|
456
|
+
# === Rio I/O
|
457
|
+
#
|
458
|
+
# As stated above the the three steps to using a Rio are:
|
459
|
+
# * Creating a Rio
|
460
|
+
# * Configuring a Rio
|
461
|
+
# * Doing I/O
|
462
|
+
#
|
463
|
+
# This section describes that final step.
|
464
|
+
#
|
465
|
+
# After creating and configuring a Rio, the file-system has not been
|
466
|
+
# accessed, no socket has been opened, not so much as a test for a files
|
467
|
+
# existance has been done. When an I/O method is called on a Rio, the
|
468
|
+
# sequence of events required to complete that operation on the
|
469
|
+
# underlying object takes place. Rio takes care of creating the
|
470
|
+
# appropriate object (eg IO,Dir), opening the object with the appropriate
|
471
|
+
# mode, performing the operation, closing the object if required, and
|
472
|
+
# returning the results of the operation.
|
473
|
+
#
|
474
|
+
# Rio's I/O operations can be divide into two catagories:
|
475
|
+
# * Proxy operations
|
476
|
+
# * Grande operations
|
477
|
+
#
|
478
|
+
# ==== Proxy operations
|
479
|
+
#
|
480
|
+
# These are calls which are forwarded to the underlying object (eg
|
481
|
+
# IO,Dir,Net::FTP), after appropriately creating and configuring that
|
482
|
+
# object. The result produced by the method is returned, and the object
|
483
|
+
# is closed.
|
484
|
+
#
|
485
|
+
# In some cases the result is modified before being returned, as when a
|
486
|
+
# Rio is configured with {#chomp}[rdoc-ref:IF::GrandeStream#chomp].
|
487
|
+
#
|
488
|
+
# In all cases, if the result returned by the underlying object, could
|
489
|
+
# itself be used for further I/O operations it is returned as a Rio. For
|
490
|
+
# example: where File#dirname returns a string, {#dirname}[rdoc-ref:IF::Path#dirname] returns a
|
491
|
+
# Rio; where Dir#read returns a string representing a directory entry,
|
492
|
+
# {#read}[rdoc-ref:IF::FileOrDir#read] returns a Rio.
|
493
|
+
#
|
494
|
+
# With some noteable exceptions, most of the operations available if one
|
495
|
+
# were using the underlying Ruby I/O class are available to the Rio and
|
496
|
+
# will behave identically.
|
497
|
+
#
|
498
|
+
# For things that exist on a file system:
|
499
|
+
#
|
500
|
+
# * All the methods in FileTest are available as Rio instance
|
501
|
+
# methods. For example
|
502
|
+
#
|
503
|
+
# FileTest.file?('afile')
|
504
|
+
#
|
505
|
+
# becomes
|
506
|
+
#
|
507
|
+
# rio('afile').file?
|
508
|
+
#
|
509
|
+
# * All the instance methods of +File+ except +path+ are available to a
|
510
|
+
# rio without change
|
511
|
+
#
|
512
|
+
# * Most of the class methods of +File+ are available.
|
513
|
+
#
|
514
|
+
# * For those that take a filename as their only argument the calls
|
515
|
+
# are mapped to Rio instance methods as described above for
|
516
|
+
# FileTest.
|
517
|
+
#
|
518
|
+
# * +dirname+, and +readlink+ return Rios instead of strings
|
519
|
+
#
|
520
|
+
# * Rio has its own {#basename}[rdoc-ref:IF::Path#basename], {#join}[rdoc-ref:IF::Path#join] and {#symlink}[rdoc-ref:IF::FileOrDir#symlink], which
|
521
|
+
# provide similar functionality.
|
522
|
+
#
|
523
|
+
# * The class methods which take multiple filenames
|
524
|
+
# (+chmod+,+chown+,+lchmod+,+lchown+) are available as Rio instance
|
525
|
+
# methods. For example
|
526
|
+
#
|
527
|
+
# File.chmod(0666,'afile')
|
528
|
+
# becomes
|
529
|
+
# rio('afile').chmod(06660)
|
530
|
+
#
|
531
|
+
# For I/O Streams
|
532
|
+
#
|
533
|
+
# Most of the instance methods of IO are available, and most do the same
|
534
|
+
# thing, with some interface changes. <b>The big exception to this is
|
535
|
+
# the '<<' operator.</b> This is one of Rio's grande operators. While
|
536
|
+
# the symantics one would use to write to an IO object would actually
|
537
|
+
# accomplish the same thing with a Rio, It is a very different
|
538
|
+
# operator. Read the section on grande operators. The other differences
|
539
|
+
# between IO instance methods and the Rio equivelence can be summarized
|
540
|
+
# as follows.
|
541
|
+
#
|
542
|
+
# * The simple instance methods (eg +fcntl+, <tt>eof?</tt>,
|
543
|
+
# <tt>tty?</tt> etc.) are forwarded and the result returned as is
|
544
|
+
#
|
545
|
+
# * Anywhere IO returns an IO, Rio returns a Rio
|
546
|
+
#
|
547
|
+
# * +close+ and its cousins return the Rio.
|
548
|
+
#
|
549
|
+
# * +each_byte+ and +each_line+ are forwarded as is.
|
550
|
+
#
|
551
|
+
# * All methods which read (read*,get*,each*) will cause the file to
|
552
|
+
# closed when the end of file is reached. This behavior is
|
553
|
+
# configurable, but the default is to close on eof
|
554
|
+
#
|
555
|
+
# * The methods which write (put*,print*) are forwarded as is; put* and
|
556
|
+
# print* return the Rio; write returns the value returned by IO#write;
|
557
|
+
# as mentioned above '<<' is a grande operator in Rio.
|
558
|
+
#
|
559
|
+
# For directories:
|
560
|
+
#
|
561
|
+
# * all the instance methods of Dir are available except +each+ which is
|
562
|
+
# a grande method.
|
563
|
+
#
|
564
|
+
# * the class methods +mkdir+, +delete+, +rmdir+ are provided as
|
565
|
+
# instance methods.
|
566
|
+
#
|
567
|
+
# * +chdir+ is provided as an instance method. {#chdir}[rdoc-ref:IF::Dir#chdir] returns a Rio
|
568
|
+
# and passes a Rio to a block if one is provided.
|
569
|
+
#
|
570
|
+
# * +glob+ is provided as an instance method, but returns an array of
|
571
|
+
# Rios
|
572
|
+
#
|
573
|
+
# * +foreach+ is not supported
|
574
|
+
#
|
575
|
+
# * +each+ and <tt>[]</tt> have similar functionality provided by Rio
|
576
|
+
#
|
577
|
+
#
|
578
|
+
# For other Rios, instance methods are generally forwarded where
|
579
|
+
# appropriate. For example
|
580
|
+
#
|
581
|
+
# * Rios that refer to StringIO objects forward 'string' and 'string='
|
582
|
+
#
|
583
|
+
# * Rios that refer to http URIs support all the Meta methods provided
|
584
|
+
# by open-uri
|
585
|
+
#
|
586
|
+
#
|
587
|
+
# ==== Grande operators
|
588
|
+
#
|
589
|
+
# The primary grande operator is {#each}[rdoc-ref:IF::Grande#each]. +each+ is used to iterate
|
590
|
+
# through Rios. When applied to a file it iterates through records in
|
591
|
+
# the file. When applied to a directory it iterates through the entries
|
592
|
+
# in the directory. Its behavior is modified by configuring the Rio
|
593
|
+
# prior to calling it using the configuration methods discussed
|
594
|
+
# above. Since iterating through things is ubiquitous in ruby, it is
|
595
|
+
# implied by the presence of a block after any of the grande
|
596
|
+
# configuration methods and many times does not need to be call
|
597
|
+
# explicitly. For example:
|
598
|
+
#
|
599
|
+
# # iterate through chomped ruby comment lines
|
600
|
+
# rio('afile.rb').chomp.lines(/^\s*#/) { |line| ... }
|
601
|
+
#
|
602
|
+
# # iterate through all .rb files in 'adir' and its subdirectories
|
603
|
+
# rio('adir').all.files('*.rb') { |f| ... }
|
604
|
+
#
|
605
|
+
# Because a Rio is an Enumerable, it supports +to_a+, which is the basis
|
606
|
+
# for the grande subscript operator. {#[]}[rdoc-ref:IF::Grande#[]] with no arguments simply
|
607
|
+
# calls to_a. With arguments it behaves as if those arguments had been
|
608
|
+
# passed to the most recently called of the grande selection methods
|
609
|
+
# listed above, and then calls to_a. For example to get the first ten
|
610
|
+
# lines of a file into an array with lines chomped
|
611
|
+
#
|
612
|
+
# rio('afile').chomp.lines(0...10).to_a
|
613
|
+
#
|
614
|
+
# can be written as
|
615
|
+
#
|
616
|
+
# rio('afile.gz').chomp.lines[0...10]
|
617
|
+
#
|
618
|
+
# or, to create an array of all the .c files in a directory, one could
|
619
|
+
# write
|
620
|
+
#
|
621
|
+
# rio('adir').files['*.c']
|
622
|
+
#
|
623
|
+
# The other grande operators are its copy operators. They are:
|
624
|
+
#
|
625
|
+
# * <tt><</tt> (copy-from)
|
626
|
+
#
|
627
|
+
# * <tt><<</tt> (append-from)
|
628
|
+
#
|
629
|
+
# * <tt>></tt> (copy-to)
|
630
|
+
#
|
631
|
+
# * <tt>>></tt> (append-to)
|
632
|
+
#
|
633
|
+
# The only difference between the 'copy' and 'append' versions is how
|
634
|
+
# they deal with an unopened resource. In the former the open it with
|
635
|
+
# mode 'w' and in the latter, mode 'a'. Beyond that, their behavior can
|
636
|
+
# be summarized as:
|
637
|
+
#
|
638
|
+
# source.each do |entry|
|
639
|
+
# destination << entry
|
640
|
+
# end
|
641
|
+
#
|
642
|
+
# Since they are based on the +each+ operator, all of the selection and
|
643
|
+
# configuration options are available. And the right-hand-side argument
|
644
|
+
# of the operators are not restricted to Rios -- Strings and Arrays are
|
645
|
+
# also supported.
|
646
|
+
#
|
647
|
+
# For example:
|
648
|
+
#
|
649
|
+
# rio('afile') > astring # copy a file into a string
|
650
|
+
#
|
651
|
+
# rio('afile').chomp > anarray # copy the chomped lines of afile into an array
|
652
|
+
#
|
653
|
+
# rio('afile.gz').gzip.lines(0...100) > rio('bfile') # copy 100 lines from a gzipped file into another file
|
654
|
+
#
|
655
|
+
# rio(?-) < rio('http://rubydoc.org/') # copy a web page to stdout
|
656
|
+
#
|
657
|
+
# rio('bdir') < rio('adir') # copy an entire directory structure
|
658
|
+
#
|
659
|
+
# rio('adir').dirs.files('README') > rio('bdir') # same thing, but only README files
|
660
|
+
#
|
661
|
+
# rio(?-,'ps -a').skiplines(0,/ps$/) > anarray # copy the output of th ps command into an array, skippying
|
662
|
+
# # the header line and the ps command entry
|
663
|
+
#
|
664
|
+
# === Renaming and Moving
|
665
|
+
#
|
666
|
+
# Rio provides two methods for directly renaming objects on the
|
667
|
+
# filesystem: {#rename}[rdoc-ref:IF::FileOrDir#rename] and {#rename!}[rdoc-ref:IF::FileOrDir#rename!].
|
668
|
+
# Both of these use File#rename.
|
669
|
+
# The difference between them is the returned Rio.
|
670
|
+
# {#rename}[rdoc-ref:IF::FileOrDir#rename] leaves the path of the Rio unchanged,
|
671
|
+
# while {#rename!}[rdoc-ref:IF::FileOrDir#rename!] changes the path of the Rio to refer
|
672
|
+
# to the renamed path.
|
673
|
+
#
|
674
|
+
# ario = rio('a')
|
675
|
+
# ario.rename('b') # file 'a' has been renamed to 'b' but 'ario' => rio('a')
|
676
|
+
# ario.rename!('b') # file 'a' has been renamed to 'b' and 'ario' => rio('b')
|
677
|
+
#
|
678
|
+
# Rio also has a +rename+ mode, which causes the path manipulation
|
679
|
+
# methods {#dirname=}[rdoc-ref:IF::Path#dirname=], {#filename=}[rdoc-ref:IF::Path#filename=], {#basename=}[rdoc-ref:IF::Path#basename=] and
|
680
|
+
# {#extname=}[rdoc-ref:IF::Path#extname=] to rename an object on the filesystem when they are
|
681
|
+
# used to change a Rio's path. A Rio is put in +rename+ mode by calling
|
682
|
+
# {#rename}[rdoc-ref:IF::FileOrDir#rename] with no arguments.
|
683
|
+
#
|
684
|
+
# rio('adir/afile.txt').rename.filename = 'bfile.rb' # adir/afile.txt => adir/bfile.rb
|
685
|
+
# rio('adir/afile.txt').rename.basename = 'bfile' # adir/afile.txt => adir/bfile.txt
|
686
|
+
# rio('adir/afile.txt').rename.extname = '.rb' # adir/afile.txt => adir/afile.rb
|
687
|
+
# rio('adir/afile.txt').rename.dirname = 'b/c' # adir/afile.txt => b/c/afile.txt
|
688
|
+
#
|
689
|
+
# When +rename+ mode is set for a directory Rio, it is automatically set
|
690
|
+
# in the Rios created when iterating through that directory.
|
691
|
+
#
|
692
|
+
# rio('adir').rename.files('*.htm') do |frio|
|
693
|
+
# frio.extname = '.html' #=> changes the rio and renames the file
|
694
|
+
# end
|
695
|
+
#
|
696
|
+
# === Deleting
|
697
|
+
#
|
698
|
+
# The Rio methods for deleting filesystem objects are {#rm}[rdoc-ref:IF::File#rm], {#rmdir}[rdoc-ref:IF::Dir#rmdir],
|
699
|
+
# {#rmtree}[rdoc-ref:IF::Dir#rmtree], {#delete}[rdoc-ref:IF::Grande#delete], and {#delete!}[rdoc-ref:IF::Grande#delete!]. +rm+, +rmdir+ and +rmtree+
|
700
|
+
# are passed the like named methods in the FileUtils module. {#delete}[rdoc-ref:IF::Grande#delete]
|
701
|
+
# calls +rmdir+ for directories and +rm+ for anything else, while
|
702
|
+
# {#delete!}[rdoc-ref:IF::Grande#delete!] calls {#rmtree}[rdoc-ref:IF::Dir#rmtree] for directories.
|
703
|
+
#
|
704
|
+
# * To delete something only if it is not a directory use {#rm}[rdoc-ref:IF::File#rm]
|
705
|
+
# * To delete an empty directory use {#rmdir}[rdoc-ref:IF::Dir#rmdir]
|
706
|
+
# * To delete an entire directory tree use {#rmtree}[rdoc-ref:IF::Dir#rmtree]
|
707
|
+
# * To delete anything except a populated directory use {#delete}[rdoc-ref:IF::Grande#delete]
|
708
|
+
# * To delete anything use {#delete!}[rdoc-ref:IF::Grande#delete!]
|
709
|
+
#
|
710
|
+
# It is not an error to call any of the deleting methods on something
|
711
|
+
# that does not exist. Rio provides {#exist?}[rdoc-ref:IF::Test#exist?] and {#symlink?}[rdoc-ref:IF::Test#symlink?] to check
|
712
|
+
# if something exists (<tt>exist?</tt> returns false for symlinks to
|
713
|
+
# non-existant object even though the symlink itself exists). The
|
714
|
+
# deleting methods' purpose is to make things not exist, so calling one
|
715
|
+
# of them on something that already does not exist is considered a
|
716
|
+
# success.
|
717
|
+
#
|
718
|
+
# To create a clean copy of a directory whether or not anything with
|
719
|
+
# that name exists one might do this
|
720
|
+
#
|
721
|
+
# rio('adir').delete!.mkpath.chdir do
|
722
|
+
# # do something in adir
|
723
|
+
# end
|
724
|
+
#
|
725
|
+
# ---
|
726
|
+
#
|
727
|
+
# == Miscellany
|
728
|
+
#
|
729
|
+
#
|
730
|
+
# ==== Using Symbolic Links
|
731
|
+
#
|
732
|
+
# To create a symbolic link (symlink) to the file-system entry refered
|
733
|
+
# to by a Rio, use {#symlink}[rdoc-ref:IF::FileOrDir#symlink]. {#symlink}[rdoc-ref:IF::FileOrDir#symlink] differs from File#symlink
|
734
|
+
# in that it calculates the path from the symlink location to the Rio's
|
735
|
+
# position.
|
736
|
+
#
|
737
|
+
# File#symlink('adir/afile','adir/alink')
|
738
|
+
#
|
739
|
+
# creates a symlink in the directory 'adir' named 'alink' which
|
740
|
+
# references 'adir/afile'. From the perspective of 'alink', 'adir/afile'
|
741
|
+
# does not exist. While:
|
742
|
+
#
|
743
|
+
# rio('adir/afile').symlink('adir/alink')
|
744
|
+
#
|
745
|
+
# creates a symlink in the directory 'adir' named 'alink' which
|
746
|
+
# references 'afile'. This is the route to 'adir/afile' from the
|
747
|
+
# perspective of 'adir/alink'.
|
748
|
+
#
|
749
|
+
# Note that the return value from +symlink+ is the calling Rio and not a
|
750
|
+
# Rio refering to the symlink. This is done for consistency with the
|
751
|
+
# rest of Rio.
|
752
|
+
#
|
753
|
+
# {#symlink?}[rdoc-ref:IF::Test#symlink?] can be used to test if a file-system object is a
|
754
|
+
# symlink. A Rio is extended with {#readlink}[rdoc-ref:IF::FileOrDir#readlink], and
|
755
|
+
# {#lstat}[rdoc-ref:IF::Test#lstat] only if {#symlink?}[rdoc-ref:IF::Test#symlink?] returns true. So for
|
756
|
+
# non-symlinks, these will raise a NoMethodError. These are both passed
|
757
|
+
# to their counterparts in File. {#readlink}[rdoc-ref:IF::FileOrDir#readlink] returns a Rio
|
758
|
+
# refering to the result of File#readlink.
|
759
|
+
#
|
760
|
+
#
|
761
|
+
# ==== Using A Rio as an IO (or File or Dir)
|
762
|
+
#
|
763
|
+
# Rio supports so much of IO's interface that one might be tempted to
|
764
|
+
# pass it to a method that expects an IO. While Rio is not and is not
|
765
|
+
# intended to be a stand in for IO, this can work. It requires
|
766
|
+
# knowledge of every IO method that will be called, under any
|
767
|
+
# circumstances.
|
768
|
+
#
|
769
|
+
# Even in cases where Rio supports the required IO interface, A Rio
|
770
|
+
# feature that seems to cause the most incompatibility, is its automatic
|
771
|
+
# closing of files. To turn off all of Rio's automatic closing use
|
772
|
+
# {#noautoclose}[rdoc-ref:IF::GrandeStream#noautoclose].
|
773
|
+
#
|
774
|
+
# For example:
|
775
|
+
# require 'yaml'
|
776
|
+
# yrio = rio('ran.yaml').delete!.noautoclose
|
777
|
+
# YAML.dump( ['badger', 'elephant', 'tiger'], yrio )
|
778
|
+
# obj = YAML::load( yrio ) #=> ["badger", "tiger", "elephant"]
|
779
|
+
#
|
780
|
+
#
|
781
|
+
# ==== Automatically Closing Files
|
782
|
+
#
|
783
|
+
# Rio closes files automatically in three instances.
|
784
|
+
#
|
785
|
+
# When reading from an IO it is closed when the end of file is
|
786
|
+
# reached. While this is a reasonable thing to do in many cases,
|
787
|
+
# sometimes this is not desired. To turn Rio's automatic closing on end
|
788
|
+
# of file use {#nocloseoneof}[rdoc-ref:IF::GrandeStream#nocloseoneof] (it can be turned back on via
|
789
|
+
# {#closeoneof}[rdoc-ref:IF::GrandeStream#closeoneof])
|
790
|
+
#
|
791
|
+
# ario = rio('afile').nocloseoneof
|
792
|
+
# lines = ario[]
|
793
|
+
# ario.closed? #=> false
|
794
|
+
#
|
795
|
+
# Closing on end-of-file is necessary for many of Rio's one-liners, but
|
796
|
+
# has an implication that may be surprising at first. A Rio starts life
|
797
|
+
# as a path, not much more than a string. When one of its read methods
|
798
|
+
# is called it becomes an input stream. When the stream is closed, it
|
799
|
+
# becomes a path again. This means that when reading from a Rio, the
|
800
|
+
# end-of-file condition is seen only once before it becomes a path
|
801
|
+
# again, and will be reopened if another read operation is attempted.
|
802
|
+
#
|
803
|
+
# Another time a Rio will be closed atomatically is when writing to it
|
804
|
+
# with one of the copy operators (<tt><, <<, >, >></tt>). This behavior
|
805
|
+
# can be turned off with {#nocloseoncopy}[rdoc-ref:IF::GrandeStream#nocloseoncopy].
|
806
|
+
#
|
807
|
+
# To turn off both of thes types of automatic closing use
|
808
|
+
# {#noautoclose}[rdoc-ref:IF::GrandeStream#noautoclose].
|
809
|
+
#
|
810
|
+
# The third instance when Rio will close a file automatically is when a
|
811
|
+
# file opened for one type of access receives a method which that access
|
812
|
+
# mode does not support. So, the code
|
813
|
+
# rio('afile').puts("Hello World").gets
|
814
|
+
# will open the file for write access when the +puts+
|
815
|
+
# method is received. When +gets+ is called the file is closed and
|
816
|
+
# reopened with read access.
|
817
|
+
#
|
818
|
+
# ==== Explicitly Closing Files
|
819
|
+
#
|
820
|
+
# Rio can not determine when the client is finished writing to it, as it
|
821
|
+
# does using +eof+ on read. It is the author's understanding that Ruby
|
822
|
+
# does not support a mechanism to have code run when there are no more
|
823
|
+
# references to it -- that finalizers are not necessarily run immediatly
|
824
|
+
# upon an object's reference count reaching 0. If this understanding is
|
825
|
+
# incorrect, some of Rio's extranious ways of closing a file may be
|
826
|
+
# rethought.
|
827
|
+
#
|
828
|
+
# That being said, Rio support several ways to explicitly close a
|
829
|
+
# file. {#close}[rdoc-ref:IF::RubyIO#close] will close any open Rio.
|
830
|
+
# The output methods
|
831
|
+
# {#puts!}[rdoc-ref:IF::RubyIO#puts!], {#putc!}[rdoc-ref:IF::RubyIO#putc!], {#printf!}[rdoc-ref:IF::RubyIO#printf!], {#print!}[rdoc-ref:IF::RubyIO#print!], and {#write!}[rdoc-ref:IF::RubyIO#write!]
|
832
|
+
# behave as if their
|
833
|
+
# counterparts without the exclamation point had been called and then
|
834
|
+
# call {#close}[rdoc-ref:IF::RubyIO#close] or {#close}[rdoc-ref:IF::RubyIO#close]_write if the underlying IO object is
|
835
|
+
# opened for duplex access.
|
836
|
+
#
|
837
|
+
#
|
838
|
+
# ==== Open mode selection
|
839
|
+
#
|
840
|
+
# A Rio is typically not explicitly opened. It opens a file
|
841
|
+
# automatically when an input or output methed is called. For output
|
842
|
+
# methods Rio opens a file with mode 'w', and otherwise opens a file
|
843
|
+
# with mode 'r'. This behavior can be modified using the tersely named
|
844
|
+
# methods {#a}[rdoc-ref:IF::GrandeStream#a], {#a!}[rdoc-ref:IF::GrandeStream#a!], {#r}[rdoc-ref:IF::GrandeStream#r], {#r!}[rdoc-ref:IF::GrandeStream#r!], {#w}[rdoc-ref:IF::GrandeStream#w], and {#w!}[rdoc-ref:IF::GrandeStream#w!], which cause
|
845
|
+
# the Rio to use modes 'a','a+','r','r+','w',and 'w+' respectively.
|
846
|
+
#
|
847
|
+
# One way to append a string to a file and close it in one line is
|
848
|
+
#
|
849
|
+
# rio('afile').a.puts!("Hello World")
|
850
|
+
#
|
851
|
+
# Run a cmd that must be opened for read and write
|
852
|
+
#
|
853
|
+
# ans = rio(?-,'cat').w!.puts!("Hello Kitty").readline
|
854
|
+
#
|
855
|
+
# The automatic selection of mode can be bypassed entirely using
|
856
|
+
# {#mode}[rdoc-ref:IF::RubyIO#mode] and {#open}[rdoc-ref:IF::FileOrDir#open].
|
857
|
+
#
|
858
|
+
# If a mode is specified using +mode+, the file will still be opened
|
859
|
+
# automatically, but the mode specified in the +mode+ method will be
|
860
|
+
# used regardless of whether it makes sense.
|
861
|
+
#
|
862
|
+
# A Rio can also be opened explicitly using {#open}[rdoc-ref:IF::FileOrDir#open]. +open+ takes one
|
863
|
+
# parameter, a mode. This also will override all of Rio's automatic
|
864
|
+
# mode selection.
|
865
|
+
#
|
866
|
+
#
|
867
|
+
# ==== CSV mode
|
868
|
+
#
|
869
|
+
# Rio uses the CSV class from the Ruby standard library to provide
|
870
|
+
# support for reading and writing comma-separated-value files. Normally
|
871
|
+
# using <tt>(skip)records</tt> is identical to <tt>(skip)lines</tt> because
|
872
|
+
# while +records+ only selects and does not specify the record-type,
|
873
|
+
# +lines+ is the default.
|
874
|
+
#
|
875
|
+
# rio('afile').records(1..2)
|
876
|
+
#
|
877
|
+
# effectively means
|
878
|
+
#
|
879
|
+
# rio('afile').lines.records(1..2)
|
880
|
+
#
|
881
|
+
# The CSV extension distingishes between items selected using
|
882
|
+
# {#records}[rdoc-ref:IF::GrandeStream#records] and those selected using {#lines}[rdoc-ref:IF::GrandeStream#lines]. Rio returns records
|
883
|
+
# parsed into Arrays by the CSV library when +records+ is used, and
|
884
|
+
# returns Strings as normal when +lines+ is used. +records+ is the
|
885
|
+
# default.
|
886
|
+
#
|
887
|
+
# rio('f.csv').puts!(["h0,h1","f0,f1"])
|
888
|
+
#
|
889
|
+
# rio('f.csv').csv.records[] #==>[["h0", "h1"], ["f0", "f1"]]
|
890
|
+
# rio('f.csv').csv[] #==> same thing
|
891
|
+
# rio('f.csv').csv.lines[] #==>["h0,h1\n", "f0,f1\n"]
|
892
|
+
# rio('f.csv').csv.records[0] #==>[["h0", "h1"]]
|
893
|
+
# rio('f.csv').csv[0] #==> same thing
|
894
|
+
# rio('f.csv').csv.lines[0] #==>["h0,h1\n"]
|
895
|
+
# rio('f.csv').csv.skiprecords[0] #==>[["f0", "f1"]]
|
896
|
+
# rio('f.csv').csv.skiplines[0] #==>["f0,f1\n"]
|
897
|
+
#
|
898
|
+
# This distinction, of course, applies equally when using the copy
|
899
|
+
# operators and +each+
|
900
|
+
#
|
901
|
+
# rio('f.csv').csv[0] > rio('out').csv # out contains "f0,f1\n"
|
902
|
+
#
|
903
|
+
# rio('f.csv').csv { |array_of_fields| ... }
|
904
|
+
#
|
905
|
+
# Notice that +csv+ mode is called on both the input and output
|
906
|
+
# Rios. The +csv+ on the 'out' Rio causes it to treat an array written
|
907
|
+
# to it as an array of records which is converted into CSV format before
|
908
|
+
# writing. Without the +csv+, the output would be written as if
|
909
|
+
# Array#to_s on [["f0","f1"]] had been called
|
910
|
+
#
|
911
|
+
# rio('f.csv').csv[0] > rio('out') # out contains "f0f1"
|
912
|
+
#
|
913
|
+
# The String representing a record that is returned when using +lines+
|
914
|
+
# is extended with a +to_a+ method which will parse it into an array of
|
915
|
+
# fields. Likewise the Array returned when a record is returned using
|
916
|
+
# +records+ is extended with a modified +to_s+ which treats it as an
|
917
|
+
# array CSV fields, rather than just an array of strings.
|
918
|
+
#
|
919
|
+
# array_of_lines = rio('f.csv').csv.lines[1] #==>["f0,f1\n"]
|
920
|
+
# array_of_records = rio('f.csv').csv.records[1] #==>[["f0", "f1"]]
|
921
|
+
#
|
922
|
+
# array_of_lines[0].to_a #==>["f0", "f1"]
|
923
|
+
# array_of_records[0].to_s #==>"f0,f1"
|
924
|
+
#
|
925
|
+
# {#csv}[rdoc-ref:IF::CSV#csv] takes two optional parameters, which are passed on to the CSV
|
926
|
+
# library. They are the +field_separator+ and the +record_separator+.
|
927
|
+
#
|
928
|
+
# rio('semisep').puts!(["h0;h1","f0;f1"])
|
929
|
+
#
|
930
|
+
# rio('semisep').csv(';').to_a #==>[["h0", "h1"], ["f0", "f1"]]
|
931
|
+
#
|
932
|
+
# These are specified independently on the source and destination when
|
933
|
+
# using the copy operators.
|
934
|
+
#
|
935
|
+
# rio('semisep').csv(';') > rio('colonsep').csv(':')
|
936
|
+
# rio('colonsep').contents #==>"h0:h1\nf0:f1\n"
|
937
|
+
#
|
938
|
+
# Rio provides two methods for selecting fields from CSV records in a
|
939
|
+
# manner similar to that provided for selecting lines -- {#columns}[rdoc-ref:IF::CSV#columns] and
|
940
|
+
# {#skipcolumns}[rdoc-ref:IF::CSV#skipcolumns].
|
941
|
+
#
|
942
|
+
# rio('f.csv').puts!(["h0,h1,h2,h3","f0,f1,f2,f3"])
|
943
|
+
#
|
944
|
+
# rio('f.csv').csv.columns(0).to_a #==>[["h0"], ["f0"]]
|
945
|
+
# rio('f.csv').csv.skipcolumns(0).to_a #==>[["h1", "h2", "h3"], ["f1", "f2", "f3"]]
|
946
|
+
# rio('f.csv').csv.columns(1..2).to_a #==>[["h1", "h2"], ["f1", "f2"]]
|
947
|
+
# rio('f.csv').csv.skipcolumns(1..2).to_a #==>[["h0", "h3"], ["f0", "f3"]]
|
948
|
+
#
|
949
|
+
# {#columns}[rdoc-ref:IF::CSV#columns] can, of course be used with the +each+ and the copy
|
950
|
+
# operators:
|
951
|
+
#
|
952
|
+
# rio('f.csv').csv.columns(0..1) > rio('out').csv
|
953
|
+
# rio('out').contents #==>"h0,h1\nf0,f1\n"
|
954
|
+
#
|
955
|
+
#
|
956
|
+
# ==== YAML mode
|
957
|
+
#
|
958
|
+
# Rio uses the YAML class from the Ruby standard library to provide
|
959
|
+
# support for reading and writing YAML files. Normally
|
960
|
+
# using <tt>(skip)records</tt> is identical to <tt>(skip)lines</tt> because
|
961
|
+
# while +records+ only selects and does not specify the record-type,
|
962
|
+
# +lines+ is the default.
|
963
|
+
#
|
964
|
+
# The YAML extension distingishes between items selected using
|
965
|
+
# {#records}[rdoc-ref:IF::GrandeStream#records], {#rows}[rdoc-ref:IF::GrandeStream#rows] and {#lines}[rdoc-ref:IF::GrandeStream#lines]. Rio returns objects
|
966
|
+
# loaded via YAML#load when +records+ is used; returns the YAML text
|
967
|
+
# as a String when +rows+ is used; and
|
968
|
+
# returns lines as Strings as normal when +lines+ is used.
|
969
|
+
# +records+ is the default. In yaml-mode, <tt>(skip)records</tt> can be called
|
970
|
+
# as <tt>(skip)objects</tt> and <tt>(skip)rows</tt> can be called as
|
971
|
+
# <tt>(skip)documents</tt>
|
972
|
+
#
|
973
|
+
# To read a single YAML document, Rio provides #getobj and #load
|
974
|
+
# For example, consider the following partial 'database.yml' from
|
975
|
+
# the rails distribution:
|
976
|
+
#
|
977
|
+
# development:
|
978
|
+
# adapter: mysql
|
979
|
+
# database: rails_development
|
980
|
+
#
|
981
|
+
# test:
|
982
|
+
# adapter: mysql
|
983
|
+
# database: rails_test
|
984
|
+
#
|
985
|
+
#
|
986
|
+
# To get the object represented in the yaml file:
|
987
|
+
#
|
988
|
+
# rio('database.yml').yaml.load
|
989
|
+
# ==>{"development"=>{"adapter"=>"mysql", "database"=>"rails_development"},
|
990
|
+
# "test"=>{"adapter"=>"mysql", "database"=>"rails_test"}}
|
991
|
+
#
|
992
|
+
# Or one could read parts of the file like so:
|
993
|
+
#
|
994
|
+
# rio('database.yml').yaml.getobj['development']['database']
|
995
|
+
# ==>"rails_development"
|
996
|
+
#
|
997
|
+
# Single objects can be written using #putobj and #putobj!
|
998
|
+
# which is aliased to #dump
|
999
|
+
#
|
1000
|
+
# anobject = {
|
1001
|
+
# 'production' => {
|
1002
|
+
# 'adapter' => 'mysql',
|
1003
|
+
# 'database' => 'rails_production',
|
1004
|
+
# }
|
1005
|
+
# }
|
1006
|
+
# rio('afile.yaml').yaml.dump(anobject)
|
1007
|
+
#
|
1008
|
+
#
|
1009
|
+
# {#>}[rdoc-ref:IF::Grande#>] (copy-to) and {#>>}[rdoc-ref:IF::Grande#>>] (append-to) will fill an array with with all selected
|
1010
|
+
# YAML documents in the Rio. For non-arrays, the yaml text is copied. (This may change
|
1011
|
+
# if a useful reasonable alternative can be found)
|
1012
|
+
#
|
1013
|
+
# rio('afile.yaml').yaml > anarray # load all YAML documents from 'afile.yaml'
|
1014
|
+
#
|
1015
|
+
# Single objects can be written using {#putrec}[rdoc-ref:IF::GrandeStream#putrec] (aliased to {#putobj}[rdoc-ref:IF::YAML#putobj] and {#dump}[rdoc-ref:IF::YAML#dump])
|
1016
|
+
#
|
1017
|
+
# rio('afile.yaml').yaml.putobj(anobject)
|
1018
|
+
#
|
1019
|
+
# Single objects can be loaded using {#getrec}[rdoc-ref:IF::GrandeStream#getrec] (aliase to {#getobj}[rdoc-ref:IF::YAML#getobj] and {#load}[rdoc-ref:IF::YAML#load])
|
1020
|
+
#
|
1021
|
+
# anobject = rio('afile.yaml').yaml.getobj
|
1022
|
+
#
|
1023
|
+
# A Rio in yaml-mode is just like any other Rio. And all the things you
|
1024
|
+
# can do with any Rio come for free. They can be iterated over using
|
1025
|
+
# {#each}[rdoc-ref:IF::Grande#each] and read into an array using {#[]}[rdoc-ref:IF::Grande#[]] just like
|
1026
|
+
# any other Rio. All the selection criteria are identical also.
|
1027
|
+
#
|
1028
|
+
# Get the first three objects into an array:
|
1029
|
+
#
|
1030
|
+
# array_of_objects = rio('afile.yaml').yaml[0..2]
|
1031
|
+
#
|
1032
|
+
# Iterate over only YAML documents that are a kind_of ::Hash use:
|
1033
|
+
#
|
1034
|
+
# rio('afile.yaml').yaml(::Hash) {|ahash| ...}
|
1035
|
+
#
|
1036
|
+
# This takes advantage of the fact that the default for matching records is <tt>===</tt>
|
1037
|
+
#
|
1038
|
+
# Selecting records using a Proc can be used as normal:
|
1039
|
+
#
|
1040
|
+
# anarray = rio('afile.yaml').yaml(proc{|anobject| ...}).to_a
|
1041
|
+
#
|
1042
|
+
#
|
1043
|
+
#
|
1044
|
+
# ---
|
1045
|
+
#
|
1046
|
+
#
|
1047
|
+
# See also:
|
1048
|
+
# * RIO::Doc::SYNOPSIS
|
1049
|
+
# * RIO::Doc::HOWTO
|
1050
|
+
# * RIO::Doc::EXAMPLES
|
1051
|
+
# * RIO::Rio
|
1052
|
+
#
|
1063
1053
|
|
1064
|
-
=end
|
1065
1054
|
module INTRO
|
1066
1055
|
end
|
1067
1056
|
end
|