wishdev-rio 0.4.3.1

Sign up to get free protection for your applications and to get access to all the features.
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