rio 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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