wishdev-rio 0.4.3.1

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