rio 0.3.8 → 0.3.9

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