wishdev-rio 0.4.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (296) hide show
  1. data/COPYING +341 -0
  2. data/README +81 -0
  3. data/Rakefile +281 -0
  4. data/build_doc.rb +94 -0
  5. data/doc/ANNOUNCE +159 -0
  6. data/doc/RELEASE_NOTES +308 -0
  7. data/doc/RIOIS +215 -0
  8. data/doc/generators/template/html/rio.css +428 -0
  9. data/doc/generators/template/html/rio.rb +523 -0
  10. data/doc/generators/template/html/ugly.rb +132 -0
  11. data/doc/pkg_def.rb +60 -0
  12. data/doc/rfc1738.txt +1403 -0
  13. data/doc/rfc959.txt +3933 -0
  14. data/ex/catcsv.rb +64 -0
  15. data/ex/colx.rb +8 -0
  16. data/ex/findinruby +15 -0
  17. data/ex/findruby +14 -0
  18. data/ex/passwd_report.rb +8 -0
  19. data/ex/prompt.rb +25 -0
  20. data/ex/rgb.txt.gz +0 -0
  21. data/ex/riocat +42 -0
  22. data/ex/riogunzip +31 -0
  23. data/ex/riogzip +24 -0
  24. data/ex/rioprompt.rb +10 -0
  25. data/ex/targz2zip +17 -0
  26. data/ex/tonl +10 -0
  27. data/lib/rio/abstract_method.rb +56 -0
  28. data/lib/rio/argv.rb +56 -0
  29. data/lib/rio/arycopy.rb +43 -0
  30. data/lib/rio/assert.rb +114 -0
  31. data/lib/rio/base.rb +56 -0
  32. data/lib/rio/callstr.rb +46 -0
  33. data/lib/rio/const.rb +51 -0
  34. data/lib/rio/construct.rb +50 -0
  35. data/lib/rio/constructor.rb +258 -0
  36. data/lib/rio/context/autoclose.rb +72 -0
  37. data/lib/rio/context/copying.rb +55 -0
  38. data/lib/rio/context/cxx.rb +66 -0
  39. data/lib/rio/context/dir.rb +120 -0
  40. data/lib/rio/context/gzip.rb +50 -0
  41. data/lib/rio/context/methods.rb +182 -0
  42. data/lib/rio/context/skip.rb +66 -0
  43. data/lib/rio/context/stream.rb +229 -0
  44. data/lib/rio/context.rb +117 -0
  45. data/lib/rio/cp.rb +370 -0
  46. data/lib/rio/def.rb +53 -0
  47. data/lib/rio/dir.rb +144 -0
  48. data/lib/rio/doc/EXAMPLES.rb +299 -0
  49. data/lib/rio/doc/HOWTO.rb +737 -0
  50. data/lib/rio/doc/INDEX.rb +311 -0
  51. data/lib/rio/doc/INTRO.rb +1068 -0
  52. data/lib/rio/doc/OPTIONAL.rb +130 -0
  53. data/lib/rio/doc/SYNOPSIS.rb +183 -0
  54. data/lib/rio/doc.rb +45 -0
  55. data/lib/rio/entrysel.rb +246 -0
  56. data/lib/rio/exception/copy.rb +97 -0
  57. data/lib/rio/exception/notimplemented.rb +57 -0
  58. data/lib/rio/exception/notsupported.rb +46 -0
  59. data/lib/rio/exception/open.rb +61 -0
  60. data/lib/rio/exception/state.rb +73 -0
  61. data/lib/rio/exception.rb +41 -0
  62. data/lib/rio/ext/csv.rb +351 -0
  63. data/lib/rio/ext/if.rb +45 -0
  64. data/lib/rio/ext/mp3info.rb +80 -0
  65. data/lib/rio/ext/splitlines.rb +253 -0
  66. data/lib/rio/ext/yaml/doc.rb +133 -0
  67. data/lib/rio/ext/yaml/tie.rb +149 -0
  68. data/lib/rio/ext/yaml.rb +164 -0
  69. data/lib/rio/ext/zipfile/fs.rb +116 -0
  70. data/lib/rio/ext/zipfile/rl.rb +251 -0
  71. data/lib/rio/ext/zipfile/rootdir.rb +117 -0
  72. data/lib/rio/ext/zipfile/state.rb +161 -0
  73. data/lib/rio/ext/zipfile/wrap.rb +204 -0
  74. data/lib/rio/ext/zipfile.rb +110 -0
  75. data/lib/rio/ext.rb +138 -0
  76. data/lib/rio/factory.rb +436 -0
  77. data/lib/rio/file.rb +118 -0
  78. data/lib/rio/filter/closeoneof.rb +103 -0
  79. data/lib/rio/filter/gzip.rb +70 -0
  80. data/lib/rio/filter.rb +94 -0
  81. data/lib/rio/fs/base.rb +41 -0
  82. data/lib/rio/fs/impl.rb +122 -0
  83. data/lib/rio/fs/native.rb +75 -0
  84. data/lib/rio/fs/stream.rb +61 -0
  85. data/lib/rio/fs/url.rb +63 -0
  86. data/lib/rio/ftp/conncache.rb +101 -0
  87. data/lib/rio/ftp/dir.rb +94 -0
  88. data/lib/rio/ftp/fs.rb +180 -0
  89. data/lib/rio/ftp/ftpfile.rb +20 -0
  90. data/lib/rio/grande.rb +97 -0
  91. data/lib/rio/handle.rb +100 -0
  92. data/lib/rio/if/basic.rb +64 -0
  93. data/lib/rio/if/csv.rb +76 -0
  94. data/lib/rio/if/dir.rb +157 -0
  95. data/lib/rio/if/file.rb +89 -0
  96. data/lib/rio/if/fileordir.rb +268 -0
  97. data/lib/rio/if/grande.rb +729 -0
  98. data/lib/rio/if/grande_entry.rb +379 -0
  99. data/lib/rio/if/grande_stream.rb +693 -0
  100. data/lib/rio/if/internal.rb +125 -0
  101. data/lib/rio/if/path.rb +462 -0
  102. data/lib/rio/if/rubyio.rb +681 -0
  103. data/lib/rio/if/string.rb +83 -0
  104. data/lib/rio/if/temp.rb +45 -0
  105. data/lib/rio/if/test.rb +282 -0
  106. data/lib/rio/if/yaml.rb +206 -0
  107. data/lib/rio/if.rb +64 -0
  108. data/lib/rio/ioh.rb +162 -0
  109. data/lib/rio/iomode.rb +109 -0
  110. data/lib/rio/ios/fail.rb +106 -0
  111. data/lib/rio/ios/generic.rb +119 -0
  112. data/lib/rio/ios/mode.rb +60 -0
  113. data/lib/rio/ios/null.rb +119 -0
  114. data/lib/rio/iowrap.rb +128 -0
  115. data/lib/rio/kernel.rb +54 -0
  116. data/lib/rio/local.rb +62 -0
  117. data/lib/rio/match.rb +53 -0
  118. data/lib/rio/matchrecord.rb +283 -0
  119. data/lib/rio/no_warn.rb +49 -0
  120. data/lib/rio/nullio.rb +159 -0
  121. data/lib/rio/open3.rb +68 -0
  122. data/lib/rio/ops/construct.rb +61 -0
  123. data/lib/rio/ops/create.rb +77 -0
  124. data/lib/rio/ops/dir.rb +346 -0
  125. data/lib/rio/ops/either.rb +134 -0
  126. data/lib/rio/ops/file.rb +102 -0
  127. data/lib/rio/ops/path.rb +296 -0
  128. data/lib/rio/ops/stream/input.rb +267 -0
  129. data/lib/rio/ops/stream/output.rb +100 -0
  130. data/lib/rio/ops/stream/read.rb +86 -0
  131. data/lib/rio/ops/stream/write.rb +57 -0
  132. data/lib/rio/ops/stream.rb +87 -0
  133. data/lib/rio/ops/symlink.rb +80 -0
  134. data/lib/rio/path/reset.rb +69 -0
  135. data/lib/rio/path.rb +129 -0
  136. data/lib/rio/piper/cp.rb +80 -0
  137. data/lib/rio/piper.rb +122 -0
  138. data/lib/rio/prompt.rb +66 -0
  139. data/lib/rio/rectype.rb +88 -0
  140. data/lib/rio/rl/base.rb +118 -0
  141. data/lib/rio/rl/builder.rb +117 -0
  142. data/lib/rio/rl/chmap.rb +66 -0
  143. data/lib/rio/rl/fs2url.rb +82 -0
  144. data/lib/rio/rl/ioi.rb +78 -0
  145. data/lib/rio/rl/path.rb +110 -0
  146. data/lib/rio/rl/pathmethods.rb +116 -0
  147. data/lib/rio/rl/uri.rb +200 -0
  148. data/lib/rio/rl/withpath.rb +296 -0
  149. data/lib/rio/scheme/aryio.rb +88 -0
  150. data/lib/rio/scheme/cmdio.rb +80 -0
  151. data/lib/rio/scheme/cmdpipe.rb +118 -0
  152. data/lib/rio/scheme/fd.rb +65 -0
  153. data/lib/rio/scheme/ftp.rb +141 -0
  154. data/lib/rio/scheme/http.rb +78 -0
  155. data/lib/rio/scheme/null.rb +55 -0
  156. data/lib/rio/scheme/path.rb +98 -0
  157. data/lib/rio/scheme/stderr.rb +55 -0
  158. data/lib/rio/scheme/stdio.rb +71 -0
  159. data/lib/rio/scheme/strio.rb +87 -0
  160. data/lib/rio/scheme/sysio.rb +63 -0
  161. data/lib/rio/scheme/tcp.rb +75 -0
  162. data/lib/rio/scheme/temp.rb +200 -0
  163. data/lib/rio/state/error.rb +72 -0
  164. data/lib/rio/state.rb +242 -0
  165. data/lib/rio/stream/base.rb +54 -0
  166. data/lib/rio/stream/duplex.rb +79 -0
  167. data/lib/rio/stream/open.rb +202 -0
  168. data/lib/rio/stream.rb +181 -0
  169. data/lib/rio/symantics.rb +45 -0
  170. data/lib/rio/tempdir.rb +132 -0
  171. data/lib/rio/to_rio/all.rb +39 -0
  172. data/lib/rio/to_rio/array.rb +39 -0
  173. data/lib/rio/to_rio/io.rb +40 -0
  174. data/lib/rio/to_rio/object.rb +42 -0
  175. data/lib/rio/to_rio/string.rb +40 -0
  176. data/lib/rio/to_rio.rb +67 -0
  177. data/lib/rio/uri/file.rb +198 -0
  178. data/lib/rio/util.rb +48 -0
  179. data/lib/rio/version.rb +51 -0
  180. data/lib/rio.rb +162 -0
  181. data/setup.rb +1360 -0
  182. data/test/bin/count_lines.rb +11 -0
  183. data/test/bin/find_lines.rb +13 -0
  184. data/test/bin/list_dir.rb +14 -0
  185. data/test/ftp/all.rb +9 -0
  186. data/test/ftp/anon_copy_data.rb +36 -0
  187. data/test/ftp/anon_misc.rb +124 -0
  188. data/test/ftp/anon_read.rb +105 -0
  189. data/test/ftp/anon_special.rb +68 -0
  190. data/test/ftp/anon_write.rb +70 -0
  191. data/test/ftp/ftp2ftp.rb +51 -0
  192. data/test/ftp/initftpfiles.rb +14 -0
  193. data/test/ftp/testdef.rb +55 -0
  194. data/test/gem_runtests.rb +15 -0
  195. data/test/http/all.rb +4 -0
  196. data/test/http/copy-from-http.rb +141 -0
  197. data/test/http/uri-meta.rb +72 -0
  198. data/test/lib/temp_server.rb +46 -0
  199. data/test/runalltests.rb +17 -0
  200. data/test/runftptests.rb +14 -0
  201. data/test/runhttp.rb +11 -0
  202. data/test/runhttptests.rb +14 -0
  203. data/test/runtests.rb +52 -0
  204. data/test/tc/abs.rb +355 -0
  205. data/test/tc/all.rb +80 -0
  206. data/test/tc/base.rb +31 -0
  207. data/test/tc/base2.rb +87 -0
  208. data/test/tc/cd1.rb +113 -0
  209. data/test/tc/clearsel.rb +68 -0
  210. data/test/tc/clone.rb +208 -0
  211. data/test/tc/closeoncopy.rb +102 -0
  212. data/test/tc/closeoneof.rb +194 -0
  213. data/test/tc/cmdpipe.rb +149 -0
  214. data/test/tc/copy-dir-samevar.rb +91 -0
  215. data/test/tc/copy-from.rb +129 -0
  216. data/test/tc/copy-to.rb +91 -0
  217. data/test/tc/copy.rb +74 -0
  218. data/test/tc/copyarray.rb +188 -0
  219. data/test/tc/copydest.rb +50 -0
  220. data/test/tc/copydir.rb +166 -0
  221. data/test/tc/copydirlines.rb +121 -0
  222. data/test/tc/copylines.rb +46 -0
  223. data/test/tc/copynonex.rb +118 -0
  224. data/test/tc/copysymlink.rb +39 -0
  225. data/test/tc/create.rb +114 -0
  226. data/test/tc/csv.rb +226 -0
  227. data/test/tc/csv2.rb +138 -0
  228. data/test/tc/csv_columns.rb +37 -0
  229. data/test/tc/csvutil.rb +56 -0
  230. data/test/tc/dir.rb +76 -0
  231. data/test/tc/dir_iter.rb +383 -0
  232. data/test/tc/dirautoclose.rb +67 -0
  233. data/test/tc/dirent.rb +178 -0
  234. data/test/tc/dirss.rb +81 -0
  235. data/test/tc/each.rb +111 -0
  236. data/test/tc/each_break.rb +243 -0
  237. data/test/tc/edf.rb +81 -0
  238. data/test/tc/empty.rb +51 -0
  239. data/test/tc/emptyriodir.rb +129 -0
  240. data/test/tc/entary.rb +227 -0
  241. data/test/tc/entsel.rb +110 -0
  242. data/test/tc/eq.rb +101 -0
  243. data/test/tc/expand_path.rb +69 -0
  244. data/test/tc/ext.rb +136 -0
  245. data/test/tc/fileno.rb +94 -0
  246. data/test/tc/files_select.rb +92 -0
  247. data/test/tc/get.rb +152 -0
  248. data/test/tc/getrec.rb +137 -0
  249. data/test/tc/gzip.rb +109 -0
  250. data/test/tc/io_each_byte.rb +60 -0
  251. data/test/tc/io_read.rb +80 -0
  252. data/test/tc/iometh.rb +149 -0
  253. data/test/tc/likeio.rb +116 -0
  254. data/test/tc/line_record_row.rb +51 -0
  255. data/test/tc/lineno.rb +196 -0
  256. data/test/tc/lines.rb +66 -0
  257. data/test/tc/misc.rb +432 -0
  258. data/test/tc/nolines.rb +204 -0
  259. data/test/tc/noqae.rb +879 -0
  260. data/test/tc/null.rb +45 -0
  261. data/test/tc/once.rb +6 -0
  262. data/test/tc/overload.rb +140 -0
  263. data/test/tc/pa.rb +158 -0
  264. data/test/tc/path_parts.rb +175 -0
  265. data/test/tc/pathop.rb +60 -0
  266. data/test/tc/paths.rb +145 -0
  267. data/test/tc/pid.rb +31 -0
  268. data/test/tc/piper.rb +143 -0
  269. data/test/tc/programs_util.rb +24 -0
  270. data/test/tc/qae.rb +493 -0
  271. data/test/tc/qae_riovar.rb +499 -0
  272. data/test/tc/readline.rb +30 -0
  273. data/test/tc/records.rb +68 -0
  274. data/test/tc/rename.rb +233 -0
  275. data/test/tc/rename_assign.rb +45 -0
  276. data/test/tc/riorl.rb +181 -0
  277. data/test/tc/route.rb +51 -0
  278. data/test/tc/selnosel.rb +33 -0
  279. data/test/tc/skip.rb +89 -0
  280. data/test/tc/skiplines.rb +71 -0
  281. data/test/tc/split.rb +28 -0
  282. data/test/tc/splitlines.rb +65 -0
  283. data/test/tc/splitpath.rb +83 -0
  284. data/test/tc/sub.rb +46 -0
  285. data/test/tc/symlink.rb +176 -0
  286. data/test/tc/symlink0.rb +348 -0
  287. data/test/tc/symlink1.rb +114 -0
  288. data/test/tc/synopsis.rb +75 -0
  289. data/test/tc/temp.rb +152 -0
  290. data/test/tc/tempdir.rb +60 -0
  291. data/test/tc/tempfile.rb +66 -0
  292. data/test/tc/testcase.rb +170 -0
  293. data/test/tc/tonl.rb +37 -0
  294. data/test/tc/truncate.rb +39 -0
  295. data/test/tc/yaml.rb +275 -0
  296. metadata +387 -0
@@ -0,0 +1,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