rio 0.3.8 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. data/README +18 -12
  2. data/Rakefile +57 -87
  3. data/build_doc.rb +19 -17
  4. data/doc/ANNOUNCE +3 -32
  5. data/doc/RELEASE_NOTES +4 -5
  6. data/doc/RIOIS +215 -0
  7. data/doc/generators/template/html/rio.css +428 -0
  8. data/doc/generators/template/html/rio.rb +18 -389
  9. data/doc/generators/template/html/ugly.rb +130 -0
  10. data/doc/pkg_def.rb +66 -0
  11. data/ex/catcsv.rb +64 -0
  12. data/ex/colx.rb +8 -0
  13. data/ex/findinruby +15 -0
  14. data/ex/findruby +14 -0
  15. data/ex/passwd_report.rb +8 -0
  16. data/ex/prompt.rb +25 -0
  17. data/ex/rgb.txt.gz +0 -0
  18. data/ex/riocat +42 -0
  19. data/ex/riogunzip +31 -0
  20. data/ex/riogzip +24 -0
  21. data/ex/rioprompt.rb +10 -0
  22. data/ex/targz2zip +17 -0
  23. data/ex/tonl +10 -0
  24. data/lib/rio.rb +16 -10
  25. data/lib/rio/abstract_method.rb +3 -4
  26. data/lib/rio/argv.rb +3 -4
  27. data/lib/rio/arycopy.rb +3 -4
  28. data/lib/rio/assert.rb +3 -4
  29. data/lib/rio/base.rb +3 -4
  30. data/lib/rio/callstr.rb +3 -4
  31. data/lib/rio/const.rb +3 -4
  32. data/lib/rio/construct.rb +3 -4
  33. data/lib/rio/constructor.rb +12 -8
  34. data/lib/rio/context.rb +15 -30
  35. data/lib/rio/context/autoclose.rb +3 -4
  36. data/lib/rio/context/copying.rb +3 -4
  37. data/lib/rio/context/cxx.rb +3 -4
  38. data/lib/rio/context/dir.rb +3 -4
  39. data/lib/rio/context/gzip.rb +3 -4
  40. data/lib/rio/context/methods.rb +16 -5
  41. data/lib/rio/context/skip.rb +3 -4
  42. data/lib/rio/context/stream.rb +42 -5
  43. data/lib/rio/cp.rb +7 -7
  44. data/lib/rio/def.rb +3 -4
  45. data/lib/rio/dir.rb +3 -4
  46. data/lib/rio/doc.rb +4 -5
  47. data/lib/rio/doc/EXAMPLES.rb +299 -0
  48. data/lib/rio/doc/HOWTO.rb +3 -4
  49. data/lib/rio/doc/INTRO.rb +86 -105
  50. data/lib/rio/doc/OPTIONAL.rb +4 -5
  51. data/lib/rio/doc/SYNOPSIS.rb +7 -6
  52. data/lib/rio/entrysel.rb +21 -23
  53. data/lib/rio/exception.rb +3 -4
  54. data/lib/rio/exception/copy.rb +3 -4
  55. data/lib/rio/exception/notimplemented.rb +57 -0
  56. data/lib/rio/exception/notsupported.rb +3 -4
  57. data/lib/rio/exception/open.rb +3 -4
  58. data/lib/rio/exception/state.rb +3 -4
  59. data/lib/rio/ext.rb +47 -13
  60. data/lib/rio/ext/csv.rb +4 -5
  61. data/lib/rio/ext/if.rb +45 -0
  62. data/lib/rio/ext/mp3info.rb +80 -0
  63. data/lib/rio/ext/splitlines.rb +253 -0
  64. data/lib/rio/ext/yaml.rb +9 -5
  65. data/lib/rio/ext/yaml/doc.rb +133 -0
  66. data/lib/rio/ext/yaml/tie.rb +149 -0
  67. data/lib/rio/ext/zipfile.rb +23 -4
  68. data/lib/rio/ext/zipfile/fs.rb +116 -0
  69. data/lib/rio/ext/zipfile/rl.rb +251 -0
  70. data/lib/rio/ext/zipfile/rootdir.rb +117 -0
  71. data/lib/rio/ext/zipfile/state.rb +161 -0
  72. data/lib/rio/ext/zipfile/wrap.rb +204 -0
  73. data/lib/rio/factory.rb +235 -27
  74. data/lib/rio/file.rb +4 -4
  75. data/lib/rio/filter.rb +3 -4
  76. data/lib/rio/filter/closeoneof.rb +3 -4
  77. data/lib/rio/filter/gzip.rb +9 -4
  78. data/lib/rio/fs/base.rb +3 -4
  79. data/lib/rio/fs/impl.rb +4 -5
  80. data/lib/rio/fs/native.rb +3 -4
  81. data/lib/rio/fs/stream.rb +3 -4
  82. data/lib/rio/fs/url.rb +3 -4
  83. data/lib/rio/ftp/conncache.rb +19 -5
  84. data/lib/rio/ftp/dir.rb +3 -4
  85. data/lib/rio/ftp/fs.rb +30 -24
  86. data/lib/rio/grande.rb +27 -7
  87. data/lib/rio/handle.rb +3 -4
  88. data/lib/rio/if.rb +19 -15
  89. data/lib/rio/if/basic.rb +7 -7
  90. data/lib/rio/if/csv.rb +5 -6
  91. data/lib/rio/if/dir.rb +120 -114
  92. data/lib/rio/if/file.rb +52 -44
  93. data/lib/rio/if/fileordir.rb +217 -211
  94. data/lib/rio/if/grande.rb +674 -644
  95. data/lib/rio/if/grande_entry.rb +321 -313
  96. data/lib/rio/if/grande_stream.rb +653 -553
  97. data/lib/rio/if/internal.rb +3 -4
  98. data/lib/rio/if/path.rb +425 -426
  99. data/lib/rio/if/rubyio.rb +681 -0
  100. data/lib/rio/if/string.rb +42 -5
  101. data/lib/rio/if/temp.rb +3 -4
  102. data/lib/rio/if/test.rb +245 -238
  103. data/lib/rio/if/yaml.rb +15 -41
  104. data/lib/rio/ioh.rb +7 -5
  105. data/lib/rio/iomode.rb +19 -7
  106. data/lib/rio/ios/fail.rb +4 -5
  107. data/lib/rio/ios/generic.rb +4 -5
  108. data/lib/rio/ios/mode.rb +4 -5
  109. data/lib/rio/ios/null.rb +6 -7
  110. data/lib/rio/iowrap.rb +3 -4
  111. data/lib/rio/kernel.rb +3 -5
  112. data/lib/rio/local.rb +3 -4
  113. data/lib/rio/match.rb +3 -4
  114. data/lib/rio/matchrecord.rb +3 -4
  115. data/lib/rio/no_warn.rb +3 -4
  116. data/lib/rio/nullio.rb +3 -4
  117. data/lib/rio/open3.rb +4 -5
  118. data/lib/rio/ops/construct.rb +3 -4
  119. data/lib/rio/ops/create.rb +11 -6
  120. data/lib/rio/ops/dir.rb +19 -8
  121. data/lib/rio/ops/either.rb +6 -5
  122. data/lib/rio/ops/file.rb +3 -4
  123. data/lib/rio/ops/path.rb +14 -35
  124. data/lib/rio/ops/stream.rb +3 -4
  125. data/lib/rio/ops/stream/input.rb +4 -7
  126. data/lib/rio/ops/stream/output.rb +3 -4
  127. data/lib/rio/ops/stream/read.rb +6 -5
  128. data/lib/rio/ops/stream/write.rb +3 -4
  129. data/lib/rio/ops/symlink.rb +3 -4
  130. data/lib/rio/path.rb +22 -18
  131. data/lib/rio/path/reset.rb +4 -5
  132. data/lib/rio/piper.rb +3 -4
  133. data/lib/rio/piper/cp.rb +3 -4
  134. data/lib/rio/prompt.rb +10 -5
  135. data/lib/rio/rectype.rb +5 -5
  136. data/lib/rio/rl/base.rb +17 -71
  137. data/lib/rio/rl/builder.rb +14 -38
  138. data/lib/rio/rl/chmap.rb +66 -0
  139. data/lib/rio/rl/fs2url.rb +82 -0
  140. data/lib/rio/rl/ioi.rb +4 -4
  141. data/lib/rio/rl/path.rb +44 -122
  142. data/lib/rio/rl/pathmethods.rb +19 -8
  143. data/lib/rio/rl/uri.rb +137 -60
  144. data/lib/rio/rl/withpath.rb +295 -0
  145. data/lib/rio/scheme/aryio.rb +3 -4
  146. data/lib/rio/scheme/cmdio.rb +3 -4
  147. data/lib/rio/scheme/cmdpipe.rb +4 -4
  148. data/lib/rio/scheme/fd.rb +3 -4
  149. data/lib/rio/scheme/ftp.rb +7 -7
  150. data/lib/rio/scheme/http.rb +4 -5
  151. data/lib/rio/scheme/null.rb +3 -4
  152. data/lib/rio/scheme/path.rb +3 -4
  153. data/lib/rio/scheme/stderr.rb +3 -4
  154. data/lib/rio/scheme/stdio.rb +3 -4
  155. data/lib/rio/scheme/strio.rb +3 -4
  156. data/lib/rio/scheme/sysio.rb +3 -4
  157. data/lib/rio/scheme/tcp.rb +3 -4
  158. data/lib/rio/scheme/temp.rb +6 -6
  159. data/lib/rio/state.rb +18 -46
  160. data/lib/rio/state/error.rb +3 -4
  161. data/lib/rio/stream.rb +4 -4
  162. data/lib/rio/stream/base.rb +3 -4
  163. data/lib/rio/stream/duplex.rb +3 -4
  164. data/lib/rio/stream/open.rb +3 -8
  165. data/lib/rio/symantics.rb +3 -4
  166. data/lib/rio/tempdir.rb +2 -2
  167. data/lib/rio/to_rio.rb +3 -4
  168. data/lib/rio/to_rio/all.rb +3 -4
  169. data/lib/rio/to_rio/array.rb +4 -5
  170. data/lib/rio/to_rio/io.rb +4 -5
  171. data/lib/rio/to_rio/object.rb +4 -5
  172. data/lib/rio/to_rio/string.rb +4 -5
  173. data/lib/rio/uri/file.rb +41 -5
  174. data/lib/rio/util.rb +3 -4
  175. data/lib/rio/version.rb +4 -5
  176. data/setup.rb +368 -339
  177. data/test/bin/list_dir.rb +1 -1
  178. data/test/ftp/anon_misc.rb +13 -1
  179. data/test/ftp/anon_special.rb +6 -6
  180. data/test/ftp/anon_write.rb +10 -3
  181. data/test/ftp/ftp2ftp.rb +2 -2
  182. data/test/ftp/testdef.rb +9 -6
  183. data/test/http/all.rb +3 -0
  184. data/test/http/copy-from-http.rb +140 -0
  185. data/test/lib/temp_server.rb +44 -0
  186. data/test/runalltests.rb +3 -1
  187. data/test/runhttp.rb +12 -0
  188. data/test/runhttptests.rb +1 -1
  189. data/test/runtests.rb +41 -3
  190. data/test/tc/abs.rb +9 -5
  191. data/test/tc/all.rb +9 -4
  192. data/test/tc/base.rb +1 -1
  193. data/test/tc/base2.rb +87 -0
  194. data/test/tc/{methods.rb → clone.rb} +72 -50
  195. data/test/tc/closeoncopy.rb +13 -2
  196. data/test/tc/copy-dir-samevar.rb +91 -0
  197. data/test/tc/dir_iter.rb +0 -1
  198. data/test/tc/empty.rb +6 -2
  199. data/test/tc/expand_path.rb +36 -54
  200. data/test/tc/ext.rb +42 -18
  201. data/test/tc/gzip.rb +30 -3
  202. data/test/tc/likeio.rb +5 -1
  203. data/test/tc/line_record_row.rb +51 -0
  204. data/test/tc/noqae.rb +71 -70
  205. data/test/tc/path_parts.rb +175 -0
  206. data/test/tc/programs_util.rb +3 -3
  207. data/test/tc/rename.rb +4 -5
  208. data/test/tc/riorl.rb +9 -7
  209. data/test/tc/skip.rb +35 -6
  210. data/test/tc/skiplines.rb +34 -5
  211. data/test/tc/split.rb +8 -50
  212. data/test/tc/splitlines.rb +65 -0
  213. data/test/tc/splitpath.rb +83 -0
  214. data/test/tc/testcase.rb +1 -1
  215. data/test/tc/truncate.rb +39 -0
  216. data/test/tc/yaml.rb +9 -8
  217. metadata +261 -207
  218. data/ChangeLog +0 -1418
  219. data/VERSION +0 -1
  220. data/lib/rio/doc/MISC.rb +0 -259
  221. data/lib/rio/if/stream.rb +0 -680
  222. data/lib/rio/impl/path.rb +0 -87
  223. data/test/tc/copy-from-http.rb +0 -89
@@ -1,6 +1,6 @@
1
1
  #--
2
2
  # ===============================================================================
3
- # Copyright (c) 2005, 2006 Christopher Kleckner
3
+ # Copyright (c) 2005,2006,2007 Christopher Kleckner
4
4
  # All rights reserved
5
5
  #
6
6
  # This file is part of the Rio library for ruby.
@@ -23,343 +23,351 @@
23
23
  #
24
24
  # To create the documentation for Rio run the command
25
25
  # ruby build_doc.rb
26
- # from the distribution directory. Then point your browser at the 'doc/rdoc' directory.
26
+ # from the distribution directory.
27
27
  #
28
28
  # Suggested Reading
29
29
  # * RIO::Doc::SYNOPSIS
30
30
  # * RIO::Doc::INTRO
31
31
  # * RIO::Doc::HOWTO
32
+ # * RIO::Doc::EXAMPLES
32
33
  # * RIO::Rio
33
34
  #
34
- # <b>Rio is pre-alpha software.
35
- # The documented interface and behavior is subject to change without notice.</b>
36
35
 
37
36
 
38
37
  module RIO
39
- class Rio
40
- # Grande Directory Selection Method
41
- #
42
- # Sets the rio to return directories. _args_ can be used to select which directories are returned.
43
- # ario.files(*args) do |f|
44
- # f.directory? #=> true
45
- # end
46
- #
47
- # No aguments selects all directories.
48
- # if _args_ are:
49
- # Regexp:: selects matching directories
50
- # glob:: selects matching directories
51
- # Proc:: called for each directory. the directory is processed unless the proc returns false
52
- # Symbol:: sent to each directory. Each directory is processed unless the symbol returns false
53
- # Fixnum:: matched against the "depth" of the directory
54
- #
55
- # If a block is given, behaves like <tt>ario.dirs(*args).each(&block)</tt>
56
- #
57
- # See also Rio#files, Rio#entries, Rio#skipdirs
58
- #
59
- # rio('adir').dirs { |frio| ... } # process all directories in 'adir'
60
- # rio('adir').all.dirs { |frio| ... } # same thing recursively
61
- # rio('adir').dirs(/^\./) { |frio| ...} # process dot directories
62
- # rio('adir').dirs[/^\./] # return an array of dot directories
63
- # rio('adir').dirs[:symlink?] # an array of symlinks to directories
64
- #
65
- def dirs(*args,&block) target.dirs(*args,&block); self end
66
-
67
- # Grande Directory Exclude Method
68
- #
69
- # If no args are provided selects anything but directories.
70
- # ario.skipdirs do |el|
71
- # el.directory? #=> false
72
- # end
73
- # If args are provided, sets the rio to select directories as with Rio#dirs, but the arguments are
74
- # used to determine which directories will *not* be processed
75
- #
76
- # If a block is given behaves like
77
- # ario.skipdirs(*args).each(&block)
78
- #
79
- # See Rio#dirs
80
- #
81
- # rio('adir').skipdirs { |ent| ... } # iterate through everything except directories
82
- # rio('adir').skipdirs(/^\./) { |drio| ... } # iterate through directories, skipping dot directories
83
- #
84
- #
85
- def skipdirs(*args,&block) target.skipdirs(*args,&block); self end
38
+ module IF
39
+ module GrandeEntry
40
+ # Grande Directory Selection Method
41
+ #
42
+ # Sets the rio to return directories. _args_ can be used to select which directories are returned.
43
+ # ario.files(*args) do |f|
44
+ # f.directory? #=> true
45
+ # end
46
+ #
47
+ # No aguments selects all directories.
48
+ # if _args_ are:
49
+ # Regexp:: selects matching directories
50
+ # glob:: selects matching directories
51
+ # Proc:: called for each directory. the directory is processed unless the proc returns false
52
+ # Symbol:: sent to each directory. Each directory is processed unless the symbol returns false
53
+ # Fixnum:: matched against the "depth" of the directory
54
+ #
55
+ # If a block is given, behaves like <tt>ario.dirs(*args).each(&block)</tt>
56
+ #
57
+ # See also #files, #entries, #skipdirs
58
+ #
59
+ # rio('adir').dirs { |frio| ... } # process all directories in 'adir'
60
+ # rio('adir').all.dirs { |frio| ... } # same thing recursively
61
+ # rio('adir').dirs(/^\./) { |frio| ...} # process dot directories
62
+ # rio('adir').dirs[/^\./] # return an array of dot directories
63
+ # rio('adir').dirs[:symlink?] # an array of symlinks to directories
64
+ #
65
+ def dirs(*args,&block) target.dirs(*args,&block); self end
66
+
67
+ # Grande Directory Exclude Method
68
+ #
69
+ # If no args are provided selects anything but directories.
70
+ # ario.skipdirs do |el|
71
+ # el.directory? #=> false
72
+ # end
73
+ # If args are provided, sets the rio to select directories as with #dirs, but the arguments are
74
+ # used to determine which directories will *not* be processed
75
+ #
76
+ # If a block is given behaves like
77
+ # ario.skipdirs(*args).each(&block)
78
+ #
79
+ # See #dirs
80
+ #
81
+ # rio('adir').skipdirs { |ent| ... } # iterate through everything except directories
82
+ # rio('adir').skipdirs(/^\./) { |drio| ... } # iterate through directories, skipping dot directories
83
+ #
84
+ #
85
+ def skipdirs(*args,&block) target.skipdirs(*args,&block); self end
86
86
 
87
87
 
88
- # Grande Directory Entry Selection Method
89
- #
90
- # No aguments selects all entries.
91
- #
92
- # if +args+ are:
93
- # Regexp:: selects matching entries
94
- # glob:: selects matching entries
95
- # Proc:: called for each entry. the entry is processed unless the proc returns false
96
- # Symbol:: sent to each entry. Each entry is processed unless the symbol returns false
97
- #
98
- # If a block is given, behaves like <tt>ario.etries(*args).each(&block)</tt>
99
- #
100
- # See also Rio#files, Rio#dirs, Rio#skipentries
101
- #
102
- # rio('adir').entries { |frio| ... } # process all entries in 'adir'
103
- # rio('adir').all.entries { |frio| ... } # same thing recursively
104
- # rio('adir').entries(/^\./) { |frio| ...} # process entries starting with a dot
105
- # rio('adir').entries[/^\./] # return an array of all entries starting with a dot
106
- # rio('adir').entries[:symlink?] # an array of symlinks in 'adir'
107
- #
108
- def entries(*args,&block) target.entries(*args,&block); self end
88
+ # Grande Directory Entry Selection Method
89
+ #
90
+ # No aguments selects all entries.
91
+ #
92
+ # if +args+ are:
93
+ # Regexp:: selects matching entries
94
+ # glob:: selects matching entries
95
+ # Proc:: called for each entry. the entry is processed unless the proc returns false
96
+ # Symbol:: sent to each entry. Each entry is processed unless the symbol returns false
97
+ #
98
+ # If a block is given, behaves like <tt>ario.etries(*args).each(&block)</tt>
99
+ #
100
+ # See also #files, #dirs, #skipentries
101
+ #
102
+ # rio('adir').entries { |frio| ... } # process all entries in 'adir'
103
+ # rio('adir').all.entries { |frio| ... } # same thing recursively
104
+ # rio('adir').entries(/^\./) { |frio| ...} # process entries starting with a dot
105
+ # rio('adir').entries[/^\./] # return an array of all entries starting with a dot
106
+ # rio('adir').entries[:symlink?] # an array of symlinks in 'adir'
107
+ #
108
+ def entries(*args,&block) target.entries(*args,&block); self end
109
109
 
110
- # Grande Directory Entry Rejection Method
111
- #
112
- # No aguments rejects all entries.
113
- #
114
- # Behaves like Rio#entries, except that matching entries are excluded.
115
- #
116
- def skipentries(*args,&block) target.skipentries(*args,&block); self end
110
+ # Grande Directory Entry Rejection Method
111
+ #
112
+ # No aguments rejects all entries.
113
+ #
114
+ # Behaves like #entries, except that matching entries are excluded.
115
+ #
116
+ # See also #entries, IF::Grande#skip
117
+ #
118
+ def skipentries(*args,&block) target.skipentries(*args,&block); self end
117
119
 
118
-
119
- # Grande File Selection Method
120
- #
121
- # Configures the rio to process files. +args+ can be used to select which files are returned.
122
- # ario.files(*args) do |f|
123
- # f.file? #=> true
124
- # end
125
- # No aguments selects all files.
126
- #
127
- # +args+ may be zero or more of the following:
128
- #
129
- # Regexp:: selects matching files
130
- # String:: treated as a glob, and selects matching files
131
- # Proc:: called for each file. the file is processed unless the proc returns false
132
- # Symbol:: sent to each file. Each file is processed unless the symbol returns false
133
- #
134
- # +files+ returns the Rio which called it. This might seem counter-intuitive at first.
135
- # One might reasonably assume that
136
- # rio('adir').files('*.rb')
137
- # would return files. It does not. It configures the rio to return files and returns
138
- # the Rio. This enables chaining for further configuration so constructs like
139
- # rio('adir').all.files('*.rb').norecurse('.svn')
140
- # are possible.
141
- #
142
- # If a block is given, behaves like
143
- # ario.files(*args).each
144
- #
145
- #
146
- # See also Rio#dirs, Rio#entries, Rio#skipfiles
147
- #
148
- # rio('adir').files { |frio| ... } # process all files in 'adir'
149
- # rio('adir').all.files { |frio| ... } # same thing recursively
150
- # rio('adir').files('*.rb') { |frio| ...} # process .rb files
151
- # rio('adir').files['*.rb'] # return an array of .rb files
152
- # rio('adir').files[/\.rb$/] # same thing using a regular expression
153
- # rio('adir').files[:symlink?] # an array of symlinks to files
154
- # rio('adir').files >> rio('other_dir') # copy files to 'other_dir'
155
- # rio('adir').files('*.rb') >> rio('other_dir') # only copy .rb files
156
- #
157
- # For Rios that refer to files, <tt>files(*args)</tt> causes the file to be processed only if
158
- # it meets the criteria specified by the args.
159
- #
160
- # rio('afile.z').files['*.z'] #=> [rio('afile.z')]
161
- # rio('afile.q').files['*.z'] #=> []
162
- #
163
- # === Example Problem
164
- #
165
- # Fill the array +ruby_progs+ with all ruby programs in a directory and its subdirectories,
166
- # skipping those in _subversion_ (.svn) directories.
167
- #
168
- # ruby_progs = []
169
- #
170
- # For the purposes of this problem, a Ruby program is defined as a file ending with .rb or a file
171
- # that is executable and whose shebang line contains 'ruby':
172
- #
173
- # is_ruby_exe = proc{ |f| f.executable? and f.gets =~ /^#!.+ruby/ }
174
- #
175
- # ==== Solution 1. Use the subscript operator.
176
- #
177
- # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
178
- #
179
- # Explanation:
180
- #
181
- # 1. Create the Rio
182
- #
183
- # Create a Rio for a directory
184
- # rio('adir')
185
- #
186
- # 2. Configure the Rio
187
- #
188
- # Specify recursion and that '.svn' directories should not be included.
189
- # rio('adir').norecurse('.svn')
190
- # Select files
191
- # rio('adir').norecurse('.svn').files
192
- # Limit to files ending with '.rb'
193
- # rio('adir').norecurse('.svn').files('*.rb')
194
- # Also allow files for whom +is_ruby_exe+ returns true
195
- # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)
196
- #
197
- # 3. Do the I/O
198
- #
199
- # Return an array rather than iterating thru them
200
- # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
201
- #
202
- # ==== Solution 2. Use the copy-to operator
203
- #
204
- # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
205
- #
206
- # Explanation:
207
- #
208
- # 1. Create the Rio
209
- #
210
- # Create a Rio for a directory
211
- # rio('adir')
212
- #
213
- # 2. Configure the Rio
214
- #
215
- # Select only files
216
- # rio('adir').files
217
- # Limit to files ending with '.rb'
218
- # rio('adir').files('*.rb')
219
- # Also allow files for whom +is_ruby_exe+ returns true
220
- # rio('adir').files('*.rb',is_ruby_exe)
221
- # Specify recursion and that '.svn' directories should not be included.
222
- # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn')
223
- #
224
- # 3. Do the I/O
225
- #
226
- # Copy the Rio to ruby_progs
227
- # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
228
- #
229
- # ==== Example Discussion
230
- #
231
- # Note that the only difference between Step 2 of Solution 1 and that of Solution 2 is
232
- # the order of the configuration methods. Step 2 of Solution 1 would have worked equally
233
- # well:
234
- #
235
- # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) > ruby_progs
236
- #
237
- # Furthermore if our problem were changed slightly and instead of having our results
238
- # ending up in an array, we wished to iterate through them, we could use:
239
- #
240
- # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) { |ruby_prog_rio| ... }
241
- #
242
- # Note the similarities. In fact, solution 1 could have been written:
243
- #
244
- # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe).to_a
245
- # or
246
- # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)[]
247
- #
248
- # Passing the arguments for +files+ to the subscript operator is syntactic sugar.
249
- # The subscript operator does not really take any arguments of its own. It always
250
- # passes them to the most recently called of the grande selection methods (or the
251
- # default selection method, if none have been called). So,
252
- #
253
- # rio('adir').files['*.rb']
254
- # is a shortcut for
255
- # rio('adir').files('*.rb').to_a
256
- #
257
- # and
258
- #
259
- # rio('adir')['*.rb']
260
- # is a shortcut for
261
- # rio('adir').entries('*.rb').to_a
262
- #
263
- # and
264
- #
265
- # rio('afile').lines[0..10]
266
- # is a shortcut for
267
- # rio('afile').lines(0..10).to_a
268
- #
269
- # And so on.
270
- #
271
- #
272
- #
273
- def files(*args,&block) target.files(*args,&block); self end
120
+
121
+ # Grande File Selection Method
122
+ #
123
+ # Configures the rio to process files. +args+ can be used to select which files are returned.
124
+ # ario.files(*args) do |f|
125
+ # f.file? #=> true
126
+ # end
127
+ # No aguments selects all files.
128
+ #
129
+ # +args+ may be zero or more of the following:
130
+ #
131
+ # Regexp:: selects matching files
132
+ # String:: treated as a glob, and selects matching files
133
+ # Proc:: called for each file. the file is processed unless the proc returns false
134
+ # Symbol:: sent to each file. Each file is processed unless the symbol returns false
135
+ #
136
+ # +files+ returns the Rio which called it. This might seem counter-intuitive at first.
137
+ # One might reasonably assume that
138
+ # rio('adir').files('*.rb')
139
+ # would return files. It does not. It configures the rio to return files and returns
140
+ # the Rio. This enables chaining for further configuration so constructs like
141
+ # rio('adir').all.files('*.rb').norecurse('.svn')
142
+ # are possible.
143
+ #
144
+ # If a block is given, behaves like
145
+ # ario.files(*args).each
146
+ #
147
+ #
148
+ # See also #dirs, #entries, #skipfiles
149
+ #
150
+ # rio('adir').files { |frio| ... } # process all files in 'adir'
151
+ # rio('adir').all.files { |frio| ... } # same thing recursively
152
+ # rio('adir').files('*.rb') { |frio| ...} # process .rb files
153
+ # rio('adir').files['*.rb'] # return an array of .rb files
154
+ # rio('adir').files[/\.rb$/] # same thing using a regular expression
155
+ # rio('adir').files[:symlink?] # an array of symlinks to files
156
+ # rio('adir').files >> rio('other_dir') # copy files to 'other_dir'
157
+ # rio('adir').files('*.rb') >> rio('other_dir') # only copy .rb files
158
+ #
159
+ # For Rios that refer to files, <tt>files(*args)</tt> causes the file to be processed only if
160
+ # it meets the criteria specified by the args.
161
+ #
162
+ # rio('afile.z').files['*.z'] #=> [rio('afile.z')]
163
+ # rio('afile.q').files['*.z'] #=> []
164
+ #
165
+ # === Example Problem
166
+ #
167
+ # Fill the array +ruby_progs+ with all ruby programs in a directory and its subdirectories,
168
+ # skipping those in _subversion_ (.svn) directories.
169
+ #
170
+ # ruby_progs = []
171
+ #
172
+ # For the purposes of this problem, a Ruby program is defined as a file ending with .rb or a file
173
+ # that is executable and whose shebang line contains 'ruby':
174
+ #
175
+ # is_ruby_exe = proc{ |f| f.executable? and f.gets =~ /^#!.+ruby/ }
176
+ #
177
+ # ==== Solution 1. Use the subscript operator.
178
+ #
179
+ # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
180
+ #
181
+ # Explanation:
182
+ #
183
+ # 1. Create the Rio
184
+ #
185
+ # Create a Rio for a directory
186
+ # rio('adir')
187
+ #
188
+ # 2. Configure the Rio
189
+ #
190
+ # Specify recursion and that '.svn' directories should not be included.
191
+ # rio('adir').norecurse('.svn')
192
+ # Select files
193
+ # rio('adir').norecurse('.svn').files
194
+ # Limit to files ending with '.rb'
195
+ # rio('adir').norecurse('.svn').files('*.rb')
196
+ # Also allow files for whom +is_ruby_exe+ returns true
197
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)
198
+ #
199
+ # 3. Do the I/O
200
+ #
201
+ # Return an array rather than iterating thru them
202
+ # ruby_progs = rio('adir').norecurse('.svn').files['*.rb',is_ruby_exe]
203
+ #
204
+ # ==== Solution 2. Use the copy-to operator
205
+ #
206
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
207
+ #
208
+ # Explanation:
209
+ #
210
+ # 1. Create the Rio
211
+ #
212
+ # Create a Rio for a directory
213
+ # rio('adir')
214
+ #
215
+ # 2. Configure the Rio
216
+ #
217
+ # Select only files
218
+ # rio('adir').files
219
+ # Limit to files ending with '.rb'
220
+ # rio('adir').files('*.rb')
221
+ # Also allow files for whom +is_ruby_exe+ returns true
222
+ # rio('adir').files('*.rb',is_ruby_exe)
223
+ # Specify recursion and that '.svn' directories should not be included.
224
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn')
225
+ #
226
+ # 3. Do the I/O
227
+ #
228
+ # Copy the Rio to ruby_progs
229
+ # rio('adir').files('*.rb',is_ruby_exe).norecurse('.svn') > ruby_progs
230
+ #
231
+ # ==== Example Discussion
232
+ #
233
+ # Note that the only difference between Step 2 of Solution 1 and that of Solution 2 is
234
+ # the order of the configuration methods. Step 2 of Solution 1 would have worked equally
235
+ # well:
236
+ #
237
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) > ruby_progs
238
+ #
239
+ # Furthermore if our problem were changed slightly and instead of having our results
240
+ # ending up in an array, we wished to iterate through them, we could use:
241
+ #
242
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe) { |ruby_prog_rio| ... }
243
+ #
244
+ # Note the similarities. In fact, solution 1 could have been written:
245
+ #
246
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe).to_a
247
+ # or
248
+ # rio('adir').norecurse('.svn').files('*.rb',is_ruby_exe)[]
249
+ #
250
+ # Passing the arguments for +files+ to the subscript operator is syntactic sugar.
251
+ # The subscript operator does not really take any arguments of its own. It always
252
+ # passes them to the most recently called of the grande selection methods (or the
253
+ # default selection method, if none have been called). So,
254
+ #
255
+ # rio('adir').files['*.rb']
256
+ # is a shortcut for
257
+ # rio('adir').files('*.rb').to_a
258
+ #
259
+ # and
260
+ #
261
+ # rio('adir')['*.rb']
262
+ # is a shortcut for
263
+ # rio('adir').entries('*.rb').to_a
264
+ #
265
+ # and
266
+ #
267
+ # rio('afile').lines[0..10]
268
+ # is a shortcut for
269
+ # rio('afile').lines(0..10).to_a
270
+ #
271
+ # And so on.
272
+ #
273
+ #
274
+ #
275
+ def files(*args,&block) target.files(*args,&block); self end
274
276
 
275
- # Grande File Exclude Method
276
- #
277
- # If no args are provided selects anything but files.
278
- # ario.skipfiles do |el|
279
- # el.file? #=> false
280
- # end
281
- # If args are provided, sets the rio to select files as with Rio#files, but the arguments are
282
- # used to determine which files will *not* be processed
283
- #
284
- # If a block is given behaves like <tt>ario.skipfiles(*args).each(&block)</tt>
285
- #
286
- # See Rio#files
287
- #
288
- # rio('adir').skipfiles { |ent| ... } # iterate through everything except files
289
- # rio('adir').skipfiles('*~') { |frio| ... } # iterate through files, skipping those ending with a tilde
290
- #
291
- #
292
- def skipfiles(*args,&block) target.skipfiles(*args,&block); self end
277
+ # Grande File Exclude Method
278
+ #
279
+ # If no args are provided selects anything but files.
280
+ # ario.skipfiles do |el|
281
+ # el.file? #=> false
282
+ # end
283
+ # If args are provided, sets the rio to select files as with #files, but the arguments are
284
+ # used to determine which files will *not* be processed
285
+ #
286
+ # If a block is given behaves like <tt>ario.skipfiles(*args).each(&block)</tt>
287
+ #
288
+ # See #files, IF::Grande#skip
289
+ #
290
+ # rio('adir').skipfiles { |ent| ... } # iterate through everything except files
291
+ # rio('adir').skipfiles('*~') { |frio| ... } # iterate through files, skipping those ending with a tilde
292
+ #
293
+ #
294
+ def skipfiles(*args,&block) target.skipfiles(*args,&block); self end
293
295
 
294
296
 
295
- # Returns +true+ if the rio is in +all+ (recursive) mode. See Rio#all
296
- #
297
- # adir = rio('adir').all.dirs
298
- # adir.all? # true
299
- # adir.each do |subdir|
300
- # subdir.all? # true
301
- # end
302
- #
303
- # rio('adir').all? # false
304
- #
305
- def all?() target.all?() end
297
+ # Returns +true+ if the rio is in +all+ (recursive) mode. See #all
298
+ #
299
+ # adir = rio('adir').all.dirs
300
+ # adir.all? # true
301
+ # adir.each do |subdir|
302
+ # subdir.all? # true
303
+ # end
304
+ #
305
+ # rio('adir').all? # false
306
+ #
307
+ def all?() target.all?() end
306
308
 
307
309
 
308
- # Grande Directory Recursion Method
309
- #
310
- # Sets the Rio to all mode (recursive)
311
- #
312
- # When called with a block, behaves as if all.each(&block) had been called
313
- #
314
- # +all+ causes subsequent calls to +files+ or +dirs+ to be applied recursively
315
- # to subdirectories
316
- #
317
- # rio('adir').all.files('*.[ch]').each { |file| ... } # process all c language source files in adir
318
- # # and all subdirectories of adir
319
- # rio('adir').all.files(/\.[ch]$/) { |file| ... } # same as above
320
- # rio('adir').files("*.[ch]").all { |file| ... } # once again
321
- # rio('adir').all.files["*.[ch]"] # same, but return an array instead of iterating
322
- #
323
- def all(arg=true,&block) target.all(arg,&block); self end
310
+ # Grande Directory Recursion Method
311
+ #
312
+ # Sets the Rio to all mode (recursive)
313
+ #
314
+ # When called with a block, behaves as if all.each(&block) had been called
315
+ #
316
+ # +all+ causes subsequent calls to +files+ or +dirs+ to be applied recursively
317
+ # to subdirectories
318
+ #
319
+ # rio('adir').all.files('*.[ch]').each { |file| ... } # process all c language source files in adir
320
+ # # and all subdirectories of adir
321
+ # rio('adir').all.files(/\.[ch]$/) { |file| ... } # same as above
322
+ # rio('adir').files("*.[ch]").all { |file| ... } # once again
323
+ # rio('adir').all.files["*.[ch]"] # same, but return an array instead of iterating
324
+ #
325
+ def all(arg=true,&block) target.all(arg,&block); self end
324
326
 
325
327
 
326
- # Grande Directory Recursion Selection Method
327
- #
328
- # Sets the Rio to recurse into directories like Rio#all. If no args are provided behaves like Rio#all.
329
- # If args are provided, they are processed like Rio#dirs, to select which subdirectories should
330
- # be recursed into. Rio#recurse always implies Rio#all.
331
- #
332
- # +args+ may be one or more of:
333
- # Regexp:: recurse into matching subdirectories
334
- # glob:: recurse into matching subdirectories
335
- # Proc:: called for each directory. The directory is recursed into unless the proc returns false
336
- # Symbol:: sent to each directory. Each directory is recursed into unless the symbol returns false
337
- # Fixnum:: recurse into directories only at the given depth
338
- # Range:: recurse into directories at a range of depths
339
- #
340
- # If a block is given, behaves like <tt>ario.recurse(*args).each(&block)</tt>
341
- #
342
- # See also Rio#norecurse, Rio#all, Rio#dirs
343
- #
344
- # rio('adir').recurse('test*') { |drio| ... } # process all entries and all entries in subdirectories
345
- # # starting with 'test' -- recursively
346
- #
347
- def recurse(*args,&block) target.recurse(*args,&block); self end
328
+ # Grande Directory Recursion Selection Method
329
+ #
330
+ # Sets the Rio to recurse into directories like #all. If no args are provided behaves like #all.
331
+ # If args are provided, they are processed like #dirs to select which subdirectories should
332
+ # be recursed into. #recurse always implies #all.
333
+ #
334
+ # +args+ may be one or more of:
335
+ # Regexp:: recurse into matching subdirectories
336
+ # glob:: recurse into matching subdirectories
337
+ # Proc:: called for each directory. The directory is recursed into unless the proc returns false
338
+ # Symbol:: sent to each directory. Each directory is recursed into unless the symbol returns false
339
+ # Fixnum:: recurse into directories only at the given depth
340
+ # Range:: recurse into directories at a range of depths
341
+ #
342
+ # If a block is given, behaves like <tt>ario.recurse(*args).each(&block)</tt>
343
+ #
344
+ # See also #norecurse, #all, #dirs
345
+ #
346
+ # rio('adir').recurse('test*') { |drio| ... } # process all entries and all entries in subdirectories
347
+ # # starting with 'test' -- recursively
348
+ #
349
+ def recurse(*args,&block) target.recurse(*args,&block); self end
348
350
 
349
351
 
350
- # Grande Directory Recursion Exclude Method
351
- #
352
- # Sets the Rio to recurse into directories like Rio#all. If no args are provided, no
353
- # directories will be recursed into. If args are provided, behaves like Rio#recurse, except
354
- # that matching directories will *not* be recursed into
355
- #
356
- # rio('adir').norecurse('.svn') { |drio| ... } # recurse, skipping subversion directories
357
- #
358
- # rio('adir').norecurse(3) {|drio| ... } # only recurse 2 levels deep into a directory structure
359
- #
360
- def norecurse(*args,&block) target.norecurse(*args,&block); self end
352
+ # Grande Directory Recursion Exclude Method
353
+ #
354
+ # Sets the Rio to recurse into directories like #all. If no args are provided, no
355
+ # directories will be recursed into. If args are provided, behaves like #recurse, except
356
+ # that matching directories will *not* be recursed into
357
+ #
358
+ # rio('adir').norecurse('.svn') { |drio| ... } # recurse, skipping subversion directories
359
+ #
360
+ # rio('adir').norecurse(3) {|drio| ... } # only recurse 2 levels deep into a directory structure
361
+ #
362
+ def norecurse(*args,&block) target.norecurse(*args,&block); self end
361
363
 
362
364
 
365
+ end
363
366
  end
364
367
  end
365
368
 
369
+ module RIO
370
+ class Rio
371
+ include RIO::IF::GrandeEntry
372
+ end
373
+ end