wishdev-rio 0.4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. data/COPYING +341 -0
  2. data/README +81 -0
  3. data/Rakefile +281 -0
  4. data/build_doc.rb +94 -0
  5. data/doc/ANNOUNCE +159 -0
  6. data/doc/RELEASE_NOTES +308 -0
  7. data/doc/RIOIS +215 -0
  8. data/doc/generators/template/html/rio.css +428 -0
  9. data/doc/generators/template/html/rio.rb +523 -0
  10. data/doc/generators/template/html/ugly.rb +132 -0
  11. data/doc/pkg_def.rb +60 -0
  12. data/doc/rfc1738.txt +1403 -0
  13. data/doc/rfc959.txt +3933 -0
  14. data/ex/catcsv.rb +64 -0
  15. data/ex/colx.rb +8 -0
  16. data/ex/findinruby +15 -0
  17. data/ex/findruby +14 -0
  18. data/ex/passwd_report.rb +8 -0
  19. data/ex/prompt.rb +25 -0
  20. data/ex/rgb.txt.gz +0 -0
  21. data/ex/riocat +42 -0
  22. data/ex/riogunzip +31 -0
  23. data/ex/riogzip +24 -0
  24. data/ex/rioprompt.rb +10 -0
  25. data/ex/targz2zip +17 -0
  26. data/ex/tonl +10 -0
  27. data/lib/rio/abstract_method.rb +56 -0
  28. data/lib/rio/argv.rb +56 -0
  29. data/lib/rio/arycopy.rb +43 -0
  30. data/lib/rio/assert.rb +114 -0
  31. data/lib/rio/base.rb +56 -0
  32. data/lib/rio/callstr.rb +46 -0
  33. data/lib/rio/const.rb +51 -0
  34. data/lib/rio/construct.rb +50 -0
  35. data/lib/rio/constructor.rb +258 -0
  36. data/lib/rio/context/autoclose.rb +72 -0
  37. data/lib/rio/context/copying.rb +55 -0
  38. data/lib/rio/context/cxx.rb +66 -0
  39. data/lib/rio/context/dir.rb +120 -0
  40. data/lib/rio/context/gzip.rb +50 -0
  41. data/lib/rio/context/methods.rb +182 -0
  42. data/lib/rio/context/skip.rb +66 -0
  43. data/lib/rio/context/stream.rb +229 -0
  44. data/lib/rio/context.rb +117 -0
  45. data/lib/rio/cp.rb +370 -0
  46. data/lib/rio/def.rb +53 -0
  47. data/lib/rio/dir.rb +144 -0
  48. data/lib/rio/doc/EXAMPLES.rb +299 -0
  49. data/lib/rio/doc/HOWTO.rb +737 -0
  50. data/lib/rio/doc/INDEX.rb +311 -0
  51. data/lib/rio/doc/INTRO.rb +1068 -0
  52. data/lib/rio/doc/OPTIONAL.rb +130 -0
  53. data/lib/rio/doc/SYNOPSIS.rb +183 -0
  54. data/lib/rio/doc.rb +45 -0
  55. data/lib/rio/entrysel.rb +246 -0
  56. data/lib/rio/exception/copy.rb +97 -0
  57. data/lib/rio/exception/notimplemented.rb +57 -0
  58. data/lib/rio/exception/notsupported.rb +46 -0
  59. data/lib/rio/exception/open.rb +61 -0
  60. data/lib/rio/exception/state.rb +73 -0
  61. data/lib/rio/exception.rb +41 -0
  62. data/lib/rio/ext/csv.rb +351 -0
  63. data/lib/rio/ext/if.rb +45 -0
  64. data/lib/rio/ext/mp3info.rb +80 -0
  65. data/lib/rio/ext/splitlines.rb +253 -0
  66. data/lib/rio/ext/yaml/doc.rb +133 -0
  67. data/lib/rio/ext/yaml/tie.rb +149 -0
  68. data/lib/rio/ext/yaml.rb +164 -0
  69. data/lib/rio/ext/zipfile/fs.rb +116 -0
  70. data/lib/rio/ext/zipfile/rl.rb +251 -0
  71. data/lib/rio/ext/zipfile/rootdir.rb +117 -0
  72. data/lib/rio/ext/zipfile/state.rb +161 -0
  73. data/lib/rio/ext/zipfile/wrap.rb +204 -0
  74. data/lib/rio/ext/zipfile.rb +110 -0
  75. data/lib/rio/ext.rb +138 -0
  76. data/lib/rio/factory.rb +436 -0
  77. data/lib/rio/file.rb +118 -0
  78. data/lib/rio/filter/closeoneof.rb +103 -0
  79. data/lib/rio/filter/gzip.rb +70 -0
  80. data/lib/rio/filter.rb +94 -0
  81. data/lib/rio/fs/base.rb +41 -0
  82. data/lib/rio/fs/impl.rb +122 -0
  83. data/lib/rio/fs/native.rb +75 -0
  84. data/lib/rio/fs/stream.rb +61 -0
  85. data/lib/rio/fs/url.rb +63 -0
  86. data/lib/rio/ftp/conncache.rb +101 -0
  87. data/lib/rio/ftp/dir.rb +94 -0
  88. data/lib/rio/ftp/fs.rb +180 -0
  89. data/lib/rio/ftp/ftpfile.rb +20 -0
  90. data/lib/rio/grande.rb +97 -0
  91. data/lib/rio/handle.rb +100 -0
  92. data/lib/rio/if/basic.rb +64 -0
  93. data/lib/rio/if/csv.rb +76 -0
  94. data/lib/rio/if/dir.rb +157 -0
  95. data/lib/rio/if/file.rb +89 -0
  96. data/lib/rio/if/fileordir.rb +268 -0
  97. data/lib/rio/if/grande.rb +729 -0
  98. data/lib/rio/if/grande_entry.rb +379 -0
  99. data/lib/rio/if/grande_stream.rb +693 -0
  100. data/lib/rio/if/internal.rb +125 -0
  101. data/lib/rio/if/path.rb +462 -0
  102. data/lib/rio/if/rubyio.rb +681 -0
  103. data/lib/rio/if/string.rb +83 -0
  104. data/lib/rio/if/temp.rb +45 -0
  105. data/lib/rio/if/test.rb +282 -0
  106. data/lib/rio/if/yaml.rb +206 -0
  107. data/lib/rio/if.rb +64 -0
  108. data/lib/rio/ioh.rb +162 -0
  109. data/lib/rio/iomode.rb +109 -0
  110. data/lib/rio/ios/fail.rb +106 -0
  111. data/lib/rio/ios/generic.rb +119 -0
  112. data/lib/rio/ios/mode.rb +60 -0
  113. data/lib/rio/ios/null.rb +119 -0
  114. data/lib/rio/iowrap.rb +128 -0
  115. data/lib/rio/kernel.rb +54 -0
  116. data/lib/rio/local.rb +62 -0
  117. data/lib/rio/match.rb +53 -0
  118. data/lib/rio/matchrecord.rb +283 -0
  119. data/lib/rio/no_warn.rb +49 -0
  120. data/lib/rio/nullio.rb +159 -0
  121. data/lib/rio/open3.rb +68 -0
  122. data/lib/rio/ops/construct.rb +61 -0
  123. data/lib/rio/ops/create.rb +77 -0
  124. data/lib/rio/ops/dir.rb +346 -0
  125. data/lib/rio/ops/either.rb +134 -0
  126. data/lib/rio/ops/file.rb +102 -0
  127. data/lib/rio/ops/path.rb +296 -0
  128. data/lib/rio/ops/stream/input.rb +267 -0
  129. data/lib/rio/ops/stream/output.rb +100 -0
  130. data/lib/rio/ops/stream/read.rb +86 -0
  131. data/lib/rio/ops/stream/write.rb +57 -0
  132. data/lib/rio/ops/stream.rb +87 -0
  133. data/lib/rio/ops/symlink.rb +80 -0
  134. data/lib/rio/path/reset.rb +69 -0
  135. data/lib/rio/path.rb +129 -0
  136. data/lib/rio/piper/cp.rb +80 -0
  137. data/lib/rio/piper.rb +122 -0
  138. data/lib/rio/prompt.rb +66 -0
  139. data/lib/rio/rectype.rb +88 -0
  140. data/lib/rio/rl/base.rb +118 -0
  141. data/lib/rio/rl/builder.rb +117 -0
  142. data/lib/rio/rl/chmap.rb +66 -0
  143. data/lib/rio/rl/fs2url.rb +82 -0
  144. data/lib/rio/rl/ioi.rb +78 -0
  145. data/lib/rio/rl/path.rb +110 -0
  146. data/lib/rio/rl/pathmethods.rb +116 -0
  147. data/lib/rio/rl/uri.rb +200 -0
  148. data/lib/rio/rl/withpath.rb +296 -0
  149. data/lib/rio/scheme/aryio.rb +88 -0
  150. data/lib/rio/scheme/cmdio.rb +80 -0
  151. data/lib/rio/scheme/cmdpipe.rb +118 -0
  152. data/lib/rio/scheme/fd.rb +65 -0
  153. data/lib/rio/scheme/ftp.rb +141 -0
  154. data/lib/rio/scheme/http.rb +78 -0
  155. data/lib/rio/scheme/null.rb +55 -0
  156. data/lib/rio/scheme/path.rb +98 -0
  157. data/lib/rio/scheme/stderr.rb +55 -0
  158. data/lib/rio/scheme/stdio.rb +71 -0
  159. data/lib/rio/scheme/strio.rb +87 -0
  160. data/lib/rio/scheme/sysio.rb +63 -0
  161. data/lib/rio/scheme/tcp.rb +75 -0
  162. data/lib/rio/scheme/temp.rb +200 -0
  163. data/lib/rio/state/error.rb +72 -0
  164. data/lib/rio/state.rb +242 -0
  165. data/lib/rio/stream/base.rb +54 -0
  166. data/lib/rio/stream/duplex.rb +79 -0
  167. data/lib/rio/stream/open.rb +202 -0
  168. data/lib/rio/stream.rb +181 -0
  169. data/lib/rio/symantics.rb +45 -0
  170. data/lib/rio/tempdir.rb +132 -0
  171. data/lib/rio/to_rio/all.rb +39 -0
  172. data/lib/rio/to_rio/array.rb +39 -0
  173. data/lib/rio/to_rio/io.rb +40 -0
  174. data/lib/rio/to_rio/object.rb +42 -0
  175. data/lib/rio/to_rio/string.rb +40 -0
  176. data/lib/rio/to_rio.rb +67 -0
  177. data/lib/rio/uri/file.rb +198 -0
  178. data/lib/rio/util.rb +48 -0
  179. data/lib/rio/version.rb +51 -0
  180. data/lib/rio.rb +162 -0
  181. data/setup.rb +1360 -0
  182. data/test/bin/count_lines.rb +11 -0
  183. data/test/bin/find_lines.rb +13 -0
  184. data/test/bin/list_dir.rb +14 -0
  185. data/test/ftp/all.rb +9 -0
  186. data/test/ftp/anon_copy_data.rb +36 -0
  187. data/test/ftp/anon_misc.rb +124 -0
  188. data/test/ftp/anon_read.rb +105 -0
  189. data/test/ftp/anon_special.rb +68 -0
  190. data/test/ftp/anon_write.rb +70 -0
  191. data/test/ftp/ftp2ftp.rb +51 -0
  192. data/test/ftp/initftpfiles.rb +14 -0
  193. data/test/ftp/testdef.rb +55 -0
  194. data/test/gem_runtests.rb +15 -0
  195. data/test/http/all.rb +4 -0
  196. data/test/http/copy-from-http.rb +141 -0
  197. data/test/http/uri-meta.rb +72 -0
  198. data/test/lib/temp_server.rb +46 -0
  199. data/test/runalltests.rb +17 -0
  200. data/test/runftptests.rb +14 -0
  201. data/test/runhttp.rb +11 -0
  202. data/test/runhttptests.rb +14 -0
  203. data/test/runtests.rb +52 -0
  204. data/test/tc/abs.rb +355 -0
  205. data/test/tc/all.rb +80 -0
  206. data/test/tc/base.rb +31 -0
  207. data/test/tc/base2.rb +87 -0
  208. data/test/tc/cd1.rb +113 -0
  209. data/test/tc/clearsel.rb +68 -0
  210. data/test/tc/clone.rb +208 -0
  211. data/test/tc/closeoncopy.rb +102 -0
  212. data/test/tc/closeoneof.rb +194 -0
  213. data/test/tc/cmdpipe.rb +149 -0
  214. data/test/tc/copy-dir-samevar.rb +91 -0
  215. data/test/tc/copy-from.rb +129 -0
  216. data/test/tc/copy-to.rb +91 -0
  217. data/test/tc/copy.rb +74 -0
  218. data/test/tc/copyarray.rb +188 -0
  219. data/test/tc/copydest.rb +50 -0
  220. data/test/tc/copydir.rb +166 -0
  221. data/test/tc/copydirlines.rb +121 -0
  222. data/test/tc/copylines.rb +46 -0
  223. data/test/tc/copynonex.rb +118 -0
  224. data/test/tc/copysymlink.rb +39 -0
  225. data/test/tc/create.rb +114 -0
  226. data/test/tc/csv.rb +226 -0
  227. data/test/tc/csv2.rb +138 -0
  228. data/test/tc/csv_columns.rb +37 -0
  229. data/test/tc/csvutil.rb +56 -0
  230. data/test/tc/dir.rb +76 -0
  231. data/test/tc/dir_iter.rb +383 -0
  232. data/test/tc/dirautoclose.rb +67 -0
  233. data/test/tc/dirent.rb +178 -0
  234. data/test/tc/dirss.rb +81 -0
  235. data/test/tc/each.rb +111 -0
  236. data/test/tc/each_break.rb +243 -0
  237. data/test/tc/edf.rb +81 -0
  238. data/test/tc/empty.rb +51 -0
  239. data/test/tc/emptyriodir.rb +129 -0
  240. data/test/tc/entary.rb +227 -0
  241. data/test/tc/entsel.rb +110 -0
  242. data/test/tc/eq.rb +101 -0
  243. data/test/tc/expand_path.rb +69 -0
  244. data/test/tc/ext.rb +136 -0
  245. data/test/tc/fileno.rb +94 -0
  246. data/test/tc/files_select.rb +92 -0
  247. data/test/tc/get.rb +152 -0
  248. data/test/tc/getrec.rb +137 -0
  249. data/test/tc/gzip.rb +109 -0
  250. data/test/tc/io_each_byte.rb +60 -0
  251. data/test/tc/io_read.rb +80 -0
  252. data/test/tc/iometh.rb +149 -0
  253. data/test/tc/likeio.rb +116 -0
  254. data/test/tc/line_record_row.rb +51 -0
  255. data/test/tc/lineno.rb +196 -0
  256. data/test/tc/lines.rb +66 -0
  257. data/test/tc/misc.rb +432 -0
  258. data/test/tc/nolines.rb +204 -0
  259. data/test/tc/noqae.rb +879 -0
  260. data/test/tc/null.rb +45 -0
  261. data/test/tc/once.rb +6 -0
  262. data/test/tc/overload.rb +140 -0
  263. data/test/tc/pa.rb +158 -0
  264. data/test/tc/path_parts.rb +175 -0
  265. data/test/tc/pathop.rb +60 -0
  266. data/test/tc/paths.rb +145 -0
  267. data/test/tc/pid.rb +31 -0
  268. data/test/tc/piper.rb +143 -0
  269. data/test/tc/programs_util.rb +24 -0
  270. data/test/tc/qae.rb +493 -0
  271. data/test/tc/qae_riovar.rb +499 -0
  272. data/test/tc/readline.rb +30 -0
  273. data/test/tc/records.rb +68 -0
  274. data/test/tc/rename.rb +233 -0
  275. data/test/tc/rename_assign.rb +45 -0
  276. data/test/tc/riorl.rb +181 -0
  277. data/test/tc/route.rb +51 -0
  278. data/test/tc/selnosel.rb +33 -0
  279. data/test/tc/skip.rb +89 -0
  280. data/test/tc/skiplines.rb +71 -0
  281. data/test/tc/split.rb +28 -0
  282. data/test/tc/splitlines.rb +65 -0
  283. data/test/tc/splitpath.rb +83 -0
  284. data/test/tc/sub.rb +46 -0
  285. data/test/tc/symlink.rb +176 -0
  286. data/test/tc/symlink0.rb +348 -0
  287. data/test/tc/symlink1.rb +114 -0
  288. data/test/tc/synopsis.rb +75 -0
  289. data/test/tc/temp.rb +152 -0
  290. data/test/tc/tempdir.rb +60 -0
  291. data/test/tc/tempfile.rb +66 -0
  292. data/test/tc/testcase.rb +170 -0
  293. data/test/tc/tonl.rb +37 -0
  294. data/test/tc/truncate.rb +39 -0
  295. data/test/tc/yaml.rb +275 -0
  296. metadata +387 -0
@@ -0,0 +1,379 @@
1
+ #--
2
+ # ===============================================================================
3
+ # Copyright (c) 2005,2006,2007 Christopher Kleckner
4
+ # All rights reserved
5
+ #
6
+ # This file is part of the Rio library for ruby.
7
+ #
8
+ # Rio is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Rio is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Rio; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # ===============================================================================
22
+ #++
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
+ module RIO
38
+ module IF
39
+ module GrandeEntry
40
+ # Grande Directory Selection Method
41
+ #
42
+ # Sets the rio to return directories. _args_ can be used to select which directories are returned.
43
+ # ario.dirs(*args) do |f|
44
+ # f.directory? #=> true
45
+ # end
46
+ #
47
+ # No aguments selects all directories.
48
+ # if _args_ are:
49
+ # Regexp:: selects matching directories
50
+ # glob:: selects matching directories
51
+ # Proc:: called for each directory. the directory is processed unless the proc returns false
52
+ # Symbol:: sent to each directory. Each directory is processed unless the symbol returns false
53
+ # Fixnum:: matched against the "depth" of the directory
54
+ #
55
+ # If a block is given, behaves like <tt>ario.dirs(*args).each(&block)</tt>
56
+ #
57
+ # See also #files, #entries, #skipdirs
58
+ #
59
+ # rio('adir').dirs { |frio| ... } # process all directories in 'adir'
60
+ # rio('adir').all.dirs { |frio| ... } # same thing recursively
61
+ # rio('adir').dirs(/^\./) { |frio| ...} # process dot directories
62
+ # rio('adir').dirs[/^\./] # return an array of dot directories
63
+ # rio('adir').dirs[:symlink?] # an array of symlinks to directories
64
+ #
65
+ # Given the directory structure 'adir/a/b/c/d'
66
+ #
67
+ # rio('adir').all.dirs[2] #=> 'adir/a/b'
68
+ # rio('adir').all.dirs[0..2] #=> 'adir/a','adir/a/b'
69
+ # rio('adir').all.skipdirs[0..2] #=> 'adir/a/b/c','adir/a/b/c/d'
70
+ #
71
+ def dirs(*args,&block) target.dirs(*args,&block); self end
72
+
73
+ # Grande Directory Exclude Method
74
+ #
75
+ # If no args are provided selects anything but directories.
76
+ # ario.skipdirs do |el|
77
+ # el.directory? #=> false
78
+ # end
79
+ # If args are provided, sets the rio to select directories as with #dirs, but the arguments are
80
+ # used to determine which directories will *not* be processed
81
+ #
82
+ # If a block is given behaves like
83
+ # ario.skipdirs(*args).each(&block)
84
+ #
85
+ # See #dirs
86
+ #
87
+ # rio('adir').skipdirs { |ent| ... } # iterate through everything except directories
88
+ # rio('adir').skipdirs(/^\./) { |drio| ... } # iterate through directories, skipping dot directories
89
+ #
90
+ #
91
+ def skipdirs(*args,&block) target.skipdirs(*args,&block); self end
92
+
93
+
94
+ # Grande Directory Entry Selection Method
95
+ #
96
+ # No aguments selects all entries.
97
+ #
98
+ # if +args+ are:
99
+ # Regexp:: selects matching entries
100
+ # glob:: selects matching entries
101
+ # Proc:: called for each entry. the entry is processed unless the proc returns false
102
+ # Symbol:: sent to each entry. Each entry is processed unless the symbol returns false
103
+ #
104
+ # If a block is given, behaves like <tt>ario.etries(*args).each(&block)</tt>
105
+ #
106
+ # See also #files, #dirs, #skipentries
107
+ #
108
+ # rio('adir').entries { |frio| ... } # process all entries in 'adir'
109
+ # rio('adir').all.entries { |frio| ... } # same thing recursively
110
+ # rio('adir').entries(/^\./) { |frio| ...} # process entries starting with a dot
111
+ # rio('adir').entries[/^\./] # return an array of all entries starting with a dot
112
+ # rio('adir').entries[:symlink?] # an array of symlinks in 'adir'
113
+ #
114
+ def entries(*args,&block) target.entries(*args,&block); self end
115
+
116
+ # Grande Directory Entry Rejection Method
117
+ #
118
+ # No aguments rejects all entries.
119
+ #
120
+ # Behaves like #entries, except that matching entries are excluded.
121
+ #
122
+ # See also #entries, IF::Grande#skip
123
+ #
124
+ def skipentries(*args,&block) target.skipentries(*args,&block); self end
125
+
126
+
127
+ # Grande File Selection Method
128
+ #
129
+ # Configures the rio to process files. +args+ can be used to select which files are returned.
130
+ # ario.files(*args) do |f|
131
+ # f.file? #=> true
132
+ # end
133
+ # No aguments selects all files.
134
+ #
135
+ # +args+ may be zero or more of the following:
136
+ #
137
+ # Regexp:: selects matching files
138
+ # String:: treated as a glob, and selects matching files
139
+ # Proc:: called for each file. the file is processed unless the proc returns false
140
+ # Symbol:: sent to each file. Each file is processed unless the symbol returns false
141
+ #
142
+ # +files+ returns the Rio which called it. This might seem counter-intuitive at first.
143
+ # One might reasonably assume that
144
+ # rio('adir').files('*.rb')
145
+ # would return files. It does not. It configures the rio to return files and returns
146
+ # the Rio. This enables chaining for further configuration so constructs like
147
+ # rio('adir').all.files('*.rb').norecurse('.svn')
148
+ # are possible.
149
+ #
150
+ # If a block is given, behaves like
151
+ # ario.files(*args).each
152
+ #
153
+ #
154
+ # See also #dirs, #entries, #skipfiles
155
+ #
156
+ # rio('adir').files { |frio| ... } # process all files in 'adir'
157
+ # rio('adir').all.files { |frio| ... } # same thing recursively
158
+ # rio('adir').files('*.rb') { |frio| ...} # process .rb files
159
+ # rio('adir').files['*.rb'] # return an array of .rb files
160
+ # rio('adir').files[/\.rb$/] # same thing using a regular expression
161
+ # rio('adir').files[:symlink?] # an array of symlinks to files
162
+ # rio('adir').files >> rio('other_dir') # copy files to 'other_dir'
163
+ # rio('adir').files('*.rb') >> rio('other_dir') # only copy .rb files
164
+ #
165
+ # For Rios that refer to files, <tt>files(*args)</tt> causes the file to be processed only if
166
+ # it meets the criteria specified by the args.
167
+ #
168
+ # rio('afile.z').files['*.z'] #=> [rio('afile.z')]
169
+ # rio('afile.q').files['*.z'] #=> []
170
+ #
171
+ # === Example Problem
172
+ #
173
+ # Fill the array +ruby_progs+ with all ruby programs in a directory and its subdirectories,
174
+ # skipping those in _subversion_ (.svn) directories.
175
+ #
176
+ # ruby_progs = []
177
+ #
178
+ # For the purposes of this problem, a Ruby program is defined as a file ending with .rb or a file
179
+ # that is executable and whose shebang line contains 'ruby':
180
+ #
181
+ # is_ruby_exe = proc{ |f| f.executable? and f.gets =~ /^#!.+ruby/ }
182
+ #
183
+ # ==== Solution 1. Use the subscript operator.
184
+ #
185
+ # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
186
+ #
187
+ # Explanation:
188
+ #
189
+ # 1. Create the Rio
190
+ #
191
+ # Create a Rio for a directory
192
+ # rio('adir')
193
+ #
194
+ # 2. Configure the Rio
195
+ #
196
+ # Specify recursion and that '.svn' directories should not be included.
197
+ # rio('adir').norecurse('.svn')
198
+ # Select files
199
+ # rio('adir').norecurse('.svn').files
200
+ # Limit to files ending with '.rb'
201
+ # rio('adir').norecurse('.svn').files('*.rb')
202
+ # Also allow files for whom +is_ruby_exe+ returns true
203
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)
204
+ #
205
+ # 3. Do the I/O
206
+ #
207
+ # Return an array rather than iterating thru them
208
+ # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
209
+ #
210
+ # ==== Solution 2. Use the copy-to operator
211
+ #
212
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
213
+ #
214
+ # Explanation:
215
+ #
216
+ # 1. Create the Rio
217
+ #
218
+ # Create a Rio for a directory
219
+ # rio('adir')
220
+ #
221
+ # 2. Configure the Rio
222
+ #
223
+ # Select only files
224
+ # rio('adir').files
225
+ # Limit to files ending with '.rb'
226
+ # rio('adir').files('*.rb')
227
+ # Also allow files for whom +is_ruby_exe+ returns true
228
+ # rio('adir').files('*.rb',is_ruby_exe)
229
+ # Specify recursion and that '.svn' directories should not be included.
230
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn')
231
+ #
232
+ # 3. Do the I/O
233
+ #
234
+ # Copy the Rio to ruby_progs
235
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
236
+ #
237
+ # ==== Example Discussion
238
+ #
239
+ # Note that the only difference between Step 2 of Solution 1 and that of Solution 2 is
240
+ # the order of the configuration methods. Step 2 of Solution 1 would have worked equally
241
+ # well:
242
+ #
243
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) > ruby_progs
244
+ #
245
+ # Furthermore if our problem were changed slightly and instead of having our results
246
+ # ending up in an array, we wished to iterate through them, we could use:
247
+ #
248
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) { |ruby_prog_rio| ... }
249
+ #
250
+ # Note the similarities. In fact, solution 1 could have been written:
251
+ #
252
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe).to_a
253
+ # or
254
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)[]
255
+ #
256
+ # Passing the arguments for +files+ to the subscript operator is syntactic sugar.
257
+ # The subscript operator does not really take any arguments of its own. It always
258
+ # passes them to the most recently called of the grande selection methods (or the
259
+ # default selection method, if none have been called). So,
260
+ #
261
+ # rio('adir').files['*.rb']
262
+ # is a shortcut for
263
+ # rio('adir').files('*.rb').to_a
264
+ #
265
+ # and
266
+ #
267
+ # rio('adir')['*.rb']
268
+ # is a shortcut for
269
+ # rio('adir').entries('*.rb').to_a
270
+ #
271
+ # and
272
+ #
273
+ # rio('afile').lines[0..10]
274
+ # is a shortcut for
275
+ # rio('afile').lines(0..10).to_a
276
+ #
277
+ # And so on.
278
+ #
279
+ #
280
+ #
281
+ def files(*args,&block) target.files(*args,&block); self end
282
+
283
+ # Grande File Exclude Method
284
+ #
285
+ # If no args are provided selects anything but files.
286
+ # ario.skipfiles do |el|
287
+ # el.file? #=> false
288
+ # end
289
+ # If args are provided, sets the rio to select files as with #files, but the arguments are
290
+ # used to determine which files will *not* be processed
291
+ #
292
+ # If a block is given behaves like <tt>ario.skipfiles(*args).each(&block)</tt>
293
+ #
294
+ # See #files, IF::Grande#skip
295
+ #
296
+ # rio('adir').skipfiles { |ent| ... } # iterate through everything except files
297
+ # rio('adir').skipfiles('*~') { |frio| ... } # iterate through files, skipping those ending with a tilde
298
+ #
299
+ #
300
+ def skipfiles(*args,&block) target.skipfiles(*args,&block); self end
301
+
302
+
303
+ # Returns +true+ if the rio is in +all+ (recursive) mode. See #all
304
+ #
305
+ # adir = rio('adir').all.dirs
306
+ # adir.all? # true
307
+ # adir.each do |subdir|
308
+ # subdir.all? # true
309
+ # end
310
+ #
311
+ # rio('adir').all? # false
312
+ #
313
+ def all?() target.all?() end
314
+
315
+
316
+ # Grande Directory Recursion Method
317
+ #
318
+ # Sets the Rio to all mode (recursive)
319
+ #
320
+ # When called with a block, behaves as if all.each(&block) had been called
321
+ #
322
+ # +all+ causes subsequent calls to +files+ or +dirs+ to be applied recursively
323
+ # to subdirectories
324
+ #
325
+ # rio('adir').all.files('*.[ch]').each { |file| ... } # process all c language source files in adir
326
+ # # and all subdirectories of adir
327
+ # rio('adir').all.files(/\.[ch]$/) { |file| ... } # same as above
328
+ # rio('adir').files("*.[ch]").all { |file| ... } # once again
329
+ # rio('adir').all.files["*.[ch]"] # same, but return an array instead of iterating
330
+ #
331
+ def all(arg=true,&block) target.all(arg,&block); self end
332
+
333
+
334
+ # Grande Directory Recursion Selection Method
335
+ #
336
+ # Sets the Rio to recurse into directories like #all. If no args are provided behaves like #all.
337
+ # If args are provided, they are processed like #dirs to select which subdirectories should
338
+ # be recursed into. #recurse always implies #all.
339
+ #
340
+ # +args+ may be one or more of:
341
+ # Regexp:: recurse into matching subdirectories
342
+ # glob:: recurse into matching subdirectories
343
+ # Proc:: called for each directory. The directory is recursed into unless the proc returns false
344
+ # Symbol:: sent to each directory. Each directory is recursed into unless the symbol returns false
345
+ # Fixnum:: recurse into directories only at the given depth
346
+ # Range:: recurse into directories at a range of depths
347
+ #
348
+ # If a block is given, behaves like <tt>ario.recurse(*args).each(&block)</tt>
349
+ #
350
+ # See also #norecurse, #all, #dirs
351
+ #
352
+ # rio('adir').recurse('test*') { |drio| ... } # process all entries and all entries in subdirectories
353
+ # # starting with 'test' -- recursively
354
+ #
355
+ def recurse(*args,&block) target.recurse(*args,&block); self end
356
+
357
+
358
+ # Grande Directory Recursion Exclude Method
359
+ #
360
+ # Sets the Rio to recurse into directories like #all. If no args are provided, no
361
+ # directories will be recursed into. If args are provided, behaves like #recurse, except
362
+ # that matching directories will *not* be recursed into
363
+ #
364
+ # rio('adir').norecurse('.svn') { |drio| ... } # recurse, skipping subversion directories
365
+ #
366
+ # rio('adir').norecurse(3) {|drio| ... } # only recurse 2 levels deep into a directory structure
367
+ #
368
+ def norecurse(*args,&block) target.norecurse(*args,&block); self end
369
+
370
+
371
+ end
372
+ end
373
+ end
374
+
375
+ module RIO
376
+ class Rio
377
+ include RIO::IF::GrandeEntry
378
+ end
379
+ end
@@ -0,0 +1,693 @@
1
+ #--
2
+ # ===============================================================================
3
+ # Copyright (c) 2005,2006,2007 Christopher Kleckner
4
+ # All rights reserved
5
+ #
6
+ # This file is part of the Rio library for ruby.
7
+ #
8
+ # Rio is free software; you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation; either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # Rio is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU General Public License
19
+ # along with Rio; if not, write to the Free Software
20
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
+ # ===============================================================================
22
+ #++
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
+ module RIO
38
+ module IF
39
+ module GrandeStream
40
+
41
+ # Calls #lines(*args) but when used with the subscript operator
42
+ # returns the first element of the returned array instead of the array.
43
+ #
44
+ # If afile contains ["line 0\n","line 1\n"]
45
+ # rio('afile').line[0] #=> "line 0\n"
46
+ # rio('afile').line[1] #=> "line 1\n"
47
+ # rio('afile').lines[0] #=> ["line 0\n"]
48
+ # rio('afile').lines[1] #=> ["line 1\n"]
49
+ # rio('afile').lines[0][0] #=> "line 0\n"
50
+ # rio('afile').lines[1][0] #=> "line 1\n"
51
+ def line(*args,&block) target.line(*args,&block); self end
52
+
53
+
54
+ # See #line.
55
+ def record(*args,&block) target.record(*args,&block); self end
56
+
57
+
58
+ # See #line.
59
+ def row(*args,&block) target.row(*args,&block); self end
60
+
61
+
62
+ # Sets the rio to read lines and returns the Rio
63
+ #
64
+ # If called with a block behaves as if <tt>lines(*args).each(&block)</tt> had been called
65
+ #
66
+ # +lines+ returns the Rio which called it. This might seem counter-intuitive at first.
67
+ # One might reasonably assume that
68
+ # rio('adir').lines(0..10)
69
+ # would return lines. It does not. It configures the rio to return lines and returns
70
+ # the Rio. This enables chaining for further configuration so constructs like
71
+ # rio('afile').lines(0..10).skiplines(/::/)
72
+ # are possible.
73
+ #
74
+ # If args are provided they may be one or more of the following:
75
+ # Regexp:: any matching record will be processed
76
+ # Range:: specifies a range of records (zero-based) to be included
77
+ # Integer:: interpreted as a one element range of lines to be processed
78
+ # Proc:: a proc which will be called for each record, records are included unless nil or false is returned
79
+ # Symbol:: a symbol which will _sent_ to each record, records are included unless nil or false is returned
80
+ # Array:: an array of other selectors. records are selected unless any of the matches fail.
81
+ #
82
+ # rio('f.txt').lines(/^\s*#/) { |line| ... } # iterate over comment-only lines
83
+ # rio('f.txt').lines(/^\s*#/).each { |line| ... } # same as above
84
+ #
85
+ # rio('f.txt').lines(1,7..9) > rio('anotherfile.txt') # copy lines 1,7,8 and 9 to anotherfile.txt
86
+ #
87
+ # rio('f.txt').lines(1...3).to_a # return an array containing lines 1 and 2 of f.txt
88
+ # rio('f.txt').lines[1...3] # same thing
89
+ #
90
+ def lines(*args,&block) target.lines(*args,&block); self end
91
+
92
+ # Sets the rio to read bytes and returns the rio
93
+ #
94
+ # _n_ specifies the number of bytes to be returned on each iteration of IF::Grande#each or by IF::GrandeStream#getrec. If _args_
95
+ # are provided, they are treated as record selectors as if <tt>ario.bytes(n).records(*args)</tt> had been
96
+ # called. See also #records, #lines, IF::Grande#each, IF::Grande#[]
97
+ #
98
+ # If called with a block behaves as if <tt>ario.bytes(n,*args).each(&block)</tt> had been called
99
+ #
100
+ # rio('f.dat').bytes(1024) { |rec| ... } # iterate through f.txt 1024 bytes at a time
101
+ # rio('f.dat').bytes(1024).each { |rec| ... } # same as above
102
+ #
103
+ # rio('f.dat').bytes(1024,0..4) { |rec| ... } # iterate through the first five 1024 byte blocks
104
+ #
105
+ # rio('f.dat').bytes(64).to_a # return the contents of f.dat as an array of 64 byte chunks
106
+ #
107
+ # rio('f.dat').bytes(512).records(0,7..9) > rio('dfile.dat') # copy 512-byte blocks 0,7,8 and 9 to dfile.dat
108
+ #
109
+ # rio('f.dat').bytes(2048).records[0...10] # return an array containing the first 10 2K blocks of f.dat
110
+ # rio('f.dat').bytes(2048)[0...10] # same thing
111
+ #
112
+ # rio('f.dat').bytes { |bytestr| ... } # iterate over f.dat 1 byte at a time.
113
+ # rio('f.dat').bytes[0...100] # returns an array of the first 100 bytes of f.dat
114
+ #
115
+ def bytes(n=1,*args,&block) target.bytes(n,*args,&block); self end
116
+
117
+
118
+ # Specifies which records will be iterated through by IF::Grande#each or returned by IF::GrandeStream#getrec
119
+ #
120
+ # If called with a block behaves as if <tt>records(*args).each(&block)</tt> had been called
121
+ #
122
+ # Returns the Rio
123
+ #
124
+ # If no args are provided, all records are selected.
125
+ # What constitutes a record is affected by #lines,#bytes,
126
+ # and extensions such as IF::CSV#csv and IF::YAML#yaml.
127
+ #
128
+ # If args are provided they may be one or more of the following:
129
+ # Regexp:: any matching record will be iterated over by IF::Grande#each or returned by IF::GrandeStream#getrec
130
+ # Integer:: specifies a record-number (zero-based) to be iterated over by IF::Grande#each or returned by IF::GrandeStream#getrec
131
+ # Range:: specifies a range of records (zero-based) to included in the iteration
132
+ # Proc:: a proc which will be called for each record, records are included unless nil or false is returned
133
+ # Symbol:: a symbol which will _sent_ to each record, records are included unless nil or false is returned
134
+ # Array:: an array of any of above. All must match for a line to be included
135
+ #
136
+ # Any other argument type is compared with the record using its <tt>===</tt> method.
137
+ #
138
+ # If the argument is a ::Proc it may be called with one, two or three paramaters.
139
+ # 1. the record
140
+ # 2. the recno (optional)
141
+ # 3. the rio (optional)
142
+ #
143
+ # Note in the following examples that since +lines+ is the default <tt>ario.records(*args)</tt>
144
+ # is effectively the same as <tt>ario.lines(*args)</tt>.
145
+ #
146
+ # rio('afile').records(0) { |line| ... } # iterate over the first line of 'afile'
147
+ # rio('afile').records(0,5..7)) { |line| ... } # iterate over lines 0,5,6 and 7
148
+ # rio('afile').records(/Zippy/) { |line| ... } # iterate over all lines containing 'Zippy'
149
+ #
150
+ #
151
+ # rio('f.csv').puts!(["h0,h1","f0,f1"]) # Create f.csv
152
+ #
153
+ # rio('f.csv').csv.records[] #==>[["h0", "h1"], ["f0", "f1"]]
154
+ # rio('f.csv').csv.lines[] #==>["h0,h1\n", "f0,f1\n"]
155
+ # rio('f.csv').csv.records[0] #==>[["h0", "h1"]]
156
+ #
157
+ def records(*args,&block) target.records(*args,&block); self end
158
+
159
+
160
+ # Specifies records which should *not* be iterated through by IF::Grande#each or returned by IF::GrandeStream#getrec
161
+ #
162
+ # If called with a block behaves as if <tt>skiprecords(*args).each(&block)</tt>
163
+ # had been called
164
+ #
165
+ # Returns the Rio
166
+ #
167
+ # See also #records, #skiplines, #lines, IF::Grande#skip
168
+ #
169
+ # If no args are provided, no records are rejected. What constitutes a record is affected by #lines,#bytes,
170
+ # and extensions such as IF::CSV#csv and IF::YAML#yaml.
171
+ #
172
+ # If args are provided they may be one or more of the following:
173
+ # Regexp:: any matching record will not be processed
174
+ # Integer:: specifies a record-number (zero-based) to be skipped
175
+ # Range:: specifies a range of records (zero-based) to be excluded
176
+ # Proc:: a proc which will be called for each record, records are excluded unless nil or false is returned
177
+ # Symbol:: a symbol which will _sent_ to each record, records are excluded unless nil or false is returned
178
+ # Array:: an array of any of the above, all of which must match for the array to match.
179
+ #
180
+ # Note in the following examples that since +lines+ is the default record
181
+ # type <tt>ario.skiprecords(*args)</tt> is effectively
182
+ # the same as <tt>ario.skiplines(*args)</tt>.
183
+ #
184
+ # rio('afile').skiprecords(0) { |line| ... } # iterate over all but the first line of 'afile'
185
+ # rio('afile').skiprecords(0,5..7)) { |line| ... } # don't iterate over lines 0,5,6 and 7
186
+ # rio('afile').skiprecords(/Zippy/) { |line| ... } # skip all lines containing 'Zippy'
187
+ # rio('afile').chomp.skiplines(:empty?) { |line| ... } # skip empty lines
188
+ #
189
+ def skiprecords(*args,&block) target.skiprecords(*args,&block); self end
190
+
191
+
192
+ # Sets the Rio to read lines and specifies lines which should *not* be iterated through by IF::Grande#each or
193
+ # returned by IF::GrandeStream#getrec
194
+ #
195
+ # If called with a block behaves as if <tt>skiplines(*args).each(&block)</tt> had been called
196
+ #
197
+ # Returns the Rio
198
+ #
199
+ # See also #lines, #records, IF::Grande#skip
200
+ #
201
+ # If no args are provided, no lines are rejected.
202
+ #
203
+ # If args are provided they may be one or more of the following:
204
+ # Regexp:: any matching line will not be processed
205
+ # Integer:: specifies a line-number (zero-based) to be skipped
206
+ # Range:: specifies a range of lines (zero-based) to be excluded
207
+ # Proc:: a proc which will be called for each line, lines are excluded unless nil or false is returned
208
+ # Symbol:: a symbol which will _sent_ to each line, lines are excluded unless nil or false is returned
209
+ # Array:: an array of any of above. All must match for a line to be included
210
+ #
211
+ # rio('afile').skiplines(0) { |line| ... } # iterate over all but the first line of 'afile'
212
+ # rio('afile').skiplines(0,5..7)) { |line| ... } # don't iterate over lines 0,5,6 and 7
213
+ # rio('afile').skiplines(/Zippy/) { |line| ... } # skip all lines containing 'Zippy'
214
+ # rio('afile').chomp.skiplines(:empty?) { |line| ... } # skip empty lines
215
+ #
216
+ def skiplines(*args,&block) target.skiplines(*args,&block); self end
217
+
218
+
219
+ # Sets the Rio to read rows and specifies rows which should be iterated through
220
+ # by IF::Grande#each or returned by IF::GrandeStream#getrec.
221
+ # #rows is intended for use by extensions, where the concept of a row is reasonable.
222
+ # In the absensence of an extension behaves like #records.
223
+ def rows(*args,&block) target.rows(*args,&block); self end
224
+
225
+
226
+ # Sets the Rio to read rows and specifies lines which should *not* be iterated
227
+ # through by IF::Grande#each or returned by IF::GrandeStream#getrec
228
+ # #skiprows is intended for use by extensions, where the concept of a row is
229
+ # reasonable. In the absence of an extension behaves like #skiprecords
230
+ def skiprows(*args,&block) target.skiprows(*args,&block); self end
231
+
232
+
233
+ # Temporarily set the Rio to read records, and call IF::Grande#get
234
+ #
235
+ # See also IF::GrandeStream#records, IF::GrandeStream#lines, IF::Grande#each, IF::Grande#[]
236
+ #
237
+ def getrec() target.getrec() end
238
+
239
+
240
+ # Temporarily set the Rio to read rows, and call IF::Grande#get
241
+ #
242
+ # See also IF::GrandeStream#rows, IF::GrandeStream#lines, IF::Grande#each, IF::Grande#[]
243
+ #
244
+ def getrow() target.getrow() end
245
+
246
+
247
+ # Temporarily set the Rio to read lines, and call IF::Grande#get
248
+ #
249
+ # See also IF::GrandeStream#records, IF::GrandeStream#lines, IF::Grande#each, IF::Grande#[]
250
+ #
251
+ def getline() target.getline() end
252
+
253
+
254
+ # Slurps the contents of the rio into a string.
255
+ #
256
+ # astring = rio('afile.txt').contents # slurp the entire contents of afile.txt into astring
257
+ #
258
+ def contents() target.contents() end
259
+
260
+
261
+ # Writes a single record to a Rio
262
+ def putrec(el) target.putrec(el) end
263
+
264
+
265
+ # Sets the implicit output mode to 'a'.
266
+ #
267
+ # This is the mode Rio will use for output when no mode is specified
268
+ #
269
+ # Rios normally don't need to be opened or have their open mode specified. A Rio determines the mode
270
+ # based on the file system object and on the action specified. For instance when a Rio encounters
271
+ # a +read+ on a file it opens the file for reading using File#open and calls IO#read; when it encounters
272
+ # a +read+ on a directory it knows to use Dir#open and call Dir#read. When it encounters a IF::RubyIO#puts, it knows
273
+ # to perform a File#open, and call IO#puts on the returned handle. By default when a method requires
274
+ # a file be opened for writing the file is opened with a mode of 'w'. #a changes this implicit
275
+ # output mode to 'a'.
276
+ #
277
+ # Note that this is not the same as setting the output mode *explicitly*, as in rio('afile').mode('a').
278
+ # When the mode is set explicitly using IF::RubyIO#mode, the mode specified will be used regardless of
279
+ # the operation being performed. The #a method only affects how Rio opens a file when
280
+ # it sees an operator that requires writing, and must determine for itself how to open it.
281
+ #
282
+ # rio('afile').puts!('Hello World') # call IO#puts on a file handle opened in 'w' mode
283
+ # rio('afile').a.puts!('Hello World') # call IO#puts on a file handle opened in 'a' mode
284
+ #
285
+ # See also #a!, #w! for setting the implicit output mode 'a+' and 'w+' respectively
286
+ #
287
+ # The methods #a, #a!, #w, #w!, #r, #r! set the +implicit+ open mode
288
+ # to 'a','a+','w','w+','r' and 'r+' respectively.
289
+ #
290
+ # See also #+@
291
+ def a() target.a(); self end
292
+
293
+
294
+ # Unary Plus. Alternate form of #a
295
+ # rio('f1') > rio('f2') # copy f1 to f2
296
+ # rio('f1') > rio('f2').a # append f1 to f2
297
+ # rio('f1') > +rio('f2') # same thing
298
+ # rio('f1') >> rio('f2') # same thing
299
+ #
300
+ def +@()
301
+ RIO::no_warn { +target }
302
+ self
303
+ end
304
+
305
+
306
+ # Sets the implicit output mode to 'a+'.
307
+ #
308
+ # The implicit output mode is the mode Rio will use for output when no mode is specified.
309
+ #
310
+ # Returns the Rio
311
+ #
312
+ # See the discussion for #a.
313
+ #
314
+ def a!() target.a!(); self end
315
+
316
+
317
+ # Sets the implicit input mode to 'r'.
318
+ #
319
+ # The implicit input mode is the mode Rio will use for input when no mode is specified.
320
+ #
321
+ # Returns the Rio
322
+ #
323
+ # See the discussion for #a.
324
+ #
325
+ # Since 'r' is the implicit input mode used by default, this method
326
+ # is probably uneeded.
327
+ #
328
+ def r() target.r(); self end
329
+
330
+
331
+ # Sets the implicit input mode to 'r+'.
332
+ #
333
+ # The implicit input mode is the mode Rio will use for input when no mode is specified.
334
+ #
335
+ # Returns the Rio
336
+ #
337
+ # See the discussion for #a.
338
+ #
339
+ def r!() target.r!(); self end
340
+
341
+
342
+ # Sets the implicit output mode to 'w'.
343
+ #
344
+ # The implicit output mode is the mode Rio will use for output when no mode is specified.
345
+ #
346
+ # Returns the Rio
347
+ #
348
+ # See the discussion for #a.
349
+ #
350
+ # Since 'w' is the implicit output mode used by default, this method
351
+ # is uneeded, but is provided for completeness..
352
+ #
353
+ def w() target.w(); self end
354
+
355
+
356
+ # Sets the implicit output mode to 'w+'.
357
+ #
358
+ # The implicit output mode is the mode Rio will use for output when no mode is specified.
359
+ #
360
+ # Returns the Rio
361
+ #
362
+ # rio(?-,'cat').w!.puts!("Hello Kitty").readline #=> "Hello Kitty"
363
+ #
364
+ # See the discussion for #a.
365
+ #
366
+ def w!() target.w!(); self end
367
+
368
+
369
+ # Set the Rio's closeoneof mode.
370
+ #
371
+ # ario.closeoneof(&block) => ario
372
+ #
373
+ # +closeoneof+ causes a Rio to be closed automatically whenever the end of
374
+ # file is reached. This affects# all methods that read from
375
+ # a rio (IF::RubyIO#readlines, #to_a, IF::Grande#each IF::RubyIO#gets etc.)
376
+ # Because +closeoneof+ must be on for many of Rio's most useful idioms,
377
+ # it is on by default. +closeoneof+ can be turned off using #nocloseoneof.
378
+ #
379
+ # If a block is given behaves like <tt>ario.closeoneof.each(&block)</tt> had been called
380
+ #
381
+ # Returns the Rio
382
+ #
383
+ # ario = rio('afile')
384
+ # lines = ario.readlines
385
+ # ario.closed? #=> true
386
+ #
387
+ # ario = rio('afile').nocloseoneof
388
+ # lines = ario.readlines
389
+ # ario.closed? #=> false
390
+ # ario.close # must be explicitly closed
391
+ #
392
+ # +closeoneof+ is ignored by directory Rios, however, setting it on a directory Rio
393
+ # causes each file Rio returned while iterating to inherit the directory's setting
394
+ #
395
+ # rio('adir').files do |file|
396
+ # file.closeoneof? #=> true
397
+ # end
398
+ #
399
+ # rio('adir').files.nocloseoneof do |file|
400
+ # file.closeoneof? #=> false
401
+ # end
402
+ #
403
+ # rio('adir').files.nocloseoneof['*.rb'] # array of .rb file Rios in adir with closeoneof off
404
+ #
405
+ # drio = rio('adir').files
406
+ # frio1 = drio.read
407
+ # frio1.closeoneof? #=> true
408
+ # drio.nocloseoneof
409
+ # frio2 = drio.read
410
+ # frio2.closeoneof? #=> false
411
+ #
412
+ #
413
+ def closeoneof(arg=true,&block) target.closeoneof(arg,&block); self end
414
+
415
+
416
+ # Set the Rio's closeoneof mode to false
417
+ # ario.nocloseoneof(&block) => ario
418
+ # See #closeoneof
419
+ #
420
+ # If a block is given behaves like
421
+ # ario.nocloseoneof.each(&block)
422
+ #
423
+ # Returns the Rio
424
+ #
425
+ # ario = rio('afile')
426
+ # lines = ario.to_a
427
+ # ario.closed? #=> true
428
+ #
429
+ # ario = rio('afile').nocloseoneof
430
+ # lines = ario.to_a
431
+ # ario.closed? #=> false
432
+ # ario.close # must be explicitly closed
433
+ def nocloseoneof(arg=false,&block) target.nocloseoneof(arg,&block); self end
434
+
435
+
436
+ # Query a Rio's closeoneof mode
437
+ # ario.closeoneof? => true or false
438
+ #
439
+ # See #closeoneof and #nocloseoneof
440
+ #
441
+ # ario = rio('afile')
442
+ # ario.closeoneof? #=> true
443
+ # lines = ario.to_a
444
+ # ario.closed? #=> true
445
+ #
446
+ # ario = rio('afile').nocloseoneof
447
+ # ario.closeoneof? #=> false
448
+ # lines = ario.to_a
449
+ # ario.closed? #=> false
450
+ # ario.close # must be explicitly closed
451
+ def closeoneof?() target.closeoneof?() end
452
+
453
+
454
+
455
+ # Set a Rio's closeoncopy mode
456
+ #
457
+ # ario.closeoncopy(&block) => ario
458
+ #
459
+ # #closeoncopy causes the Rio being written to to be closed when using
460
+ # a grande copy operator. While #closeoneof causes all Rio's to be closed
461
+ # when reading to the end of file, it does not affect Rios being written to.
462
+ # #closeoncopy only affects the Rio being written to and only when a
463
+ # grande copy operator is used. +closeoncopy+ is on by default, with one exception.
464
+ #
465
+ # dest = rio('destfile')
466
+ # dest < rio('srcfile')
467
+ # dest.closed? #=> true
468
+ #
469
+ # dest = rio('destfile').nocloseoncopy
470
+ # dest < rio('srcfile')
471
+ # dest.closed? #=> false
472
+ # dest.close # must be explicitly closed
473
+ #
474
+ # dest = rio('destfile')
475
+ # dest.print(rio('srcfile').contents)
476
+ # dest.closed? #=> false (IF::RubyIO#print is not a copy operator)
477
+ # dest.close
478
+ #
479
+ #
480
+ # ==== The Exception
481
+ #
482
+ # When a block is passed directly to the rio constructor +closeoncopy+ is turned off.
483
+ #
484
+ # rio('afile') { |file|
485
+ # file.closeoncopy? #=> false
486
+ # file < a_string
487
+ # file.closed? #=> false
488
+ # }
489
+ # # The file is now closed. See IF::GrandeStream#rio for more informatioin
490
+ #
491
+ # ==== Why?
492
+ #
493
+ # Some of my favorite Rio idioms are its copy one-liners
494
+ #
495
+ # rio('afile') < a_string # put a string into a file
496
+ # rio('afile') < an_array # put an array into a file
497
+ # rio('afile') < rio('anotherfile').lines(0..9) # copy the first 10 lines of anotherfile into afile
498
+ # rio('afile.gz').gzip < rio('anotherfile').lines(0..9) # same thing into a gzipped file
499
+ #
500
+ # In each of these cases, 'afile' would remain open after the copy and furthermore
501
+ # since the destination Rio was not saved in a variable, There is no way to close file.
502
+ # Without closeoncopy Something like this would be required:
503
+ #
504
+ # ario = rio('afile')
505
+ # ario < something_else
506
+ # ario.close
507
+ #
508
+ # Or this...
509
+ #
510
+ # ario = rio('afile') < something_else
511
+ # ario.close
512
+ #
513
+ # Or this...
514
+ #
515
+ # (rio('afile') < something_else).close
516
+ # One line, but ugly, and prone to error.
517
+ #
518
+ # What I want is this:
519
+ #
520
+ # rio('afile') < something_else
521
+ #
522
+ # Simple. I want to copy this to that, I point the arrow and it works.
523
+ #
524
+ # In perl the rio's destructor would be called, because there are no remaining references to the Rio
525
+ # However, it my understanding and experience that in Ruby the finalizer will not necessarily be
526
+ # called at this point.
527
+ #
528
+ def closeoncopy(arg=true,&block) target.closeoncopy(arg,&block); self end
529
+
530
+
531
+ # Set a Rio's closeoncopy mode to false
532
+ #
533
+ # ario.nocloseoncopy(&block) => ario
534
+ #
535
+ # See #closeoncopy
536
+ #
537
+ def nocloseoncopy(arg=false,&block) target.nocloseoncopy(arg,&block); self end
538
+
539
+
540
+ # Query a Rio's closeoncopy mode
541
+ #
542
+ # ario.closeoncopy? => true or false
543
+ #
544
+ # See #closeoncopy
545
+ #
546
+ def closeoncopy?() target.closeoncopy?() end
547
+
548
+
549
+ # Turns off both closeoneof and closeoncopy.
550
+ # Equivelent to:
551
+ # ario.nocloseoneof.nocloseoncopy
552
+ # Returns the Rio
553
+ # ario.noautoclose(&block) => ario
554
+ # If a block is given, acts as if
555
+ # ario.noautoclose.each(&block)
556
+ # had been called.
557
+ #
558
+ # See #nocloseoneof and #nocloseoncopy
559
+ #
560
+ def noautoclose(arg=false,&block) target.noautoclose(arg,&block); self end
561
+
562
+
563
+ # Queries the Rio's chomp-mode.
564
+ # See #chomp.
565
+ #
566
+ def chomp?() target.chomp?() end
567
+
568
+
569
+ # Sets the Rio to chomp lines and returns the Rio
570
+ #
571
+ # When called with a block, behaves as if <tt>chomp.each(&block)</tt> had been called
572
+ #
573
+ # chomp causes lines returned by each, to_a, readlines, readline, gets, each_line etc.
574
+ # to be chomped before iterated over or assigned
575
+ #
576
+ # rio('f.txt').chomp.each { |line| ... } # Block is called with lines already chomped
577
+ #
578
+ # rio('f.txt').chomp { |line| ... } # same as above
579
+ #
580
+ # rio('f.txt').chomp.to_a # returns the lines of f.txt chomped
581
+ #
582
+ # rio('f.txt').chomp.lines(1..2).to_a # returns an array containg lines 1 and 2 of the file after being chomped
583
+ #
584
+ # This would have similar results to rio('f.txt').lines(1..2).to_a.map{ |line| line.chomp}
585
+ #
586
+ # rio('f.txt').lines(1..2).chomp.to_a # same as above
587
+ #
588
+ # rio('f.txt').chomp.readlines # returns the lines of f.txt chomped
589
+ #
590
+ # rio('f.txt').chomp.gets # returns the first line of 'f.txt' chomped
591
+ #
592
+ # rio('f.txt').chomp > an_array # copies the chomped lines of f.txt into an_array
593
+ #
594
+ # # fill an array with all the 'require' lines in all the .rb files (recursively) in adir
595
+ # # chomping each line
596
+ #
597
+ # an_array = []
598
+ # rio('adir').chomp.all.files("*.rb") { |file|
599
+ # an_array += file.lines[/^\s*require/]
600
+ # }
601
+ #
602
+ # or simply
603
+ #
604
+ # an_array = rio('adir').chomp.all.files("*.rb").lines[/^\s*require/]
605
+ #
606
+ def chomp(arg=true,&block) target.chomp(arg,&block); self end
607
+
608
+
609
+ # Queries the Rio's strip-mode.
610
+ # See #strip.
611
+ #
612
+ def strip?() target.strip?() end
613
+
614
+
615
+ # Sets the Rio to strip lines and returns the Rio
616
+ #
617
+ # When called with a block, behaves as if strip.each(&block) had been called
618
+ #
619
+ # +strip+ causes lines returned by each, to_a, readlines, readline, gets, each_line etc.
620
+ # to be stripped with String#strip before iterated over or assigned
621
+ #
622
+ # ans = rio(?-).print("A Prompt> ").strip.gets # prompt the user
623
+ #
624
+ # See also #chomp
625
+ def strip(arg=true,&block) target.strip(arg,&block); self end
626
+
627
+
628
+ # Sets the Rio to gzip mode.
629
+ # ario.gzip #=> ario
630
+ # If applied to a Rio that is being read from Reads
631
+ # through a <tt>Zlib::GzipReader</tt>; If applied to a Rio that is being written to
632
+ # writes through a <tt>Zlib::GzipWriter</tt>.
633
+ #
634
+ # Returns the Rio
635
+ #
636
+ # If a block is given, acts like <tt>ario.gzip.each(&block)</tt>
637
+ #
638
+ # rio('afile') > rio('afile.gz').gzip # gzip a file
639
+ # rio('afile.gz').gzip < rio('afile') # same thing
640
+ #
641
+ # rio('afile.gz').gzip > rio('afile') # ungzip a file
642
+ # rio('afile') < rio('afile.gz').gzip # same thing
643
+ #
644
+ # rio('afile.gz').gzip.chomp { |line| ...} # process each chomped line of a gzipped file
645
+ # rio('afile.gz').gzip[0..9] # an array containing the first 10 lines of a gzipped file
646
+ #
647
+ def gzip(&block) target.gzip(true,&block); self end
648
+
649
+
650
+ # Queries the Rio's gzip-mode
651
+ # ario.gzip? #=> true or false
652
+ # See #gzip
653
+ #
654
+ def gzip?() target.gzip?() end
655
+
656
+
657
+ # #inputmode?
658
+ #
659
+ #
660
+ #def inputmode?() target.inputmode?() end
661
+
662
+
663
+
664
+ # This causes String#split(arg) to be called on every line
665
+ # before it is returned. An array of the split lines is
666
+ # returned when iterating
667
+ #
668
+ # rio('/etc/passwd').split(':').columns(0,2) { |ary|
669
+ # username,uid = ary
670
+ # }
671
+ #
672
+ # rio('/etc/passwd').split(':').columns(0,2).to_a #=> [[user1,uid1],[user2,uid2]]
673
+ #
674
+ # See also IF::Grande#split
675
+ #
676
+ def splitlines(*args,&block) target.splitlines(*args,&block) end
677
+
678
+
679
+
680
+ # #outputmode?
681
+ #
682
+ #
683
+ #def outputmode?() target.outputmode?() end
684
+
685
+
686
+ end
687
+ end
688
+ end
689
+ module RIO
690
+ class Rio
691
+ include RIO::IF::GrandeStream
692
+ end
693
+ end