nitro 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. data/{ChangeLog → CHANGELOG} +137 -0
  2. data/INSTALL +1 -2
  3. data/README +1 -1
  4. data/Rakefile +10 -61
  5. data/benchmark/{nitro/bench.rb → bench.rb} +1 -1
  6. data/benchmark/{nitro/simple-webrick-n-200.txt → simple-webrick-n-200.txt} +0 -0
  7. data/benchmark/{nitro/static-webrick-n-200.txt → static-webrick-n-200.txt} +0 -0
  8. data/benchmark/{nitro/tiny-lhttpd-n-200-c-5.txt → tiny-lhttpd-n-200-c-5.txt} +0 -0
  9. data/benchmark/{nitro/tiny-webrick-n-200-c-5.txt → tiny-webrick-n-200-c-5.txt} +0 -0
  10. data/benchmark/{nitro/tiny-webrick-n-200.txt → tiny-webrick-n-200.txt} +0 -0
  11. data/benchmark/{nitro/tiny2-webrick-n-200.txt → tiny2-webrick-n-200.txt} +0 -0
  12. data/doc/{ChangeLog.1 → CHANGELOG.1} +0 -0
  13. data/{RELEASES → doc/RELEASES} +46 -0
  14. data/doc/faq.txt +7 -0
  15. data/examples/README.windows +1 -1
  16. data/examples/ajax/controller.rb +21 -0
  17. data/examples/ajax/public/index.xhtml +70 -0
  18. data/examples/ajax/public/js/ajax.js +64 -0
  19. data/examples/ajax/run.rb +16 -0
  20. data/examples/blog/README +6 -3
  21. data/examples/blog/conf/apache.conf +2 -2
  22. data/examples/blog/conf/lhttpd.conf +2 -2
  23. data/examples/blog/log/apache.error_log +777 -0
  24. data/examples/blog/{root → public}/base.xsl +0 -0
  25. data/examples/blog/{root → public}/fcgi.rb +0 -0
  26. data/examples/blog/{root → public}/m/bubbles.gif +0 -0
  27. data/examples/blog/{root → public}/m/comments_curve.gif +0 -0
  28. data/examples/blog/{root → public}/m/down.gif +0 -0
  29. data/examples/blog/{root → public}/m/footer_bg.gif +0 -0
  30. data/examples/blog/{root → public}/m/garrow.gif +0 -0
  31. data/examples/blog/{root → public}/m/gbull.gif +0 -0
  32. data/examples/blog/{root → public}/m/grbull.gif +0 -0
  33. data/examples/blog/{root → public}/m/h1_bg.gif +0 -0
  34. data/examples/blog/{root → public}/m/header_bg.gif +0 -0
  35. data/examples/blog/{root → public}/m/nitro.gif +0 -0
  36. data/examples/blog/{root → public}/m/obull.gif +0 -0
  37. data/examples/blog/{root → public}/m/page_bg.gif +0 -0
  38. data/examples/blog/{root → public}/m/rss.gif +0 -0
  39. data/examples/blog/{root → public}/m/side_title_bg.gif +0 -0
  40. data/examples/blog/{root → public}/m/sidebar_bg.gif +0 -0
  41. data/examples/{no_xsl_blog/root → blog/public}/style.css +6 -0
  42. data/examples/blog/run.rb +10 -12
  43. data/examples/blog/{lib → src}/blog.rb +3 -3
  44. data/examples/blog/{lib/blog → src}/controller.rb +13 -2
  45. data/examples/blog/src/mailer.rb +23 -0
  46. data/examples/blog/{lib/blog/model.rb → src/models/blog.rb} +4 -7
  47. data/examples/blog/src/models/content.rb +52 -0
  48. data/examples/blog/src/views/blog_entry_email.xhtml +16 -0
  49. data/examples/blog/{root → src/views}/comments.xhtml +0 -0
  50. data/examples/blog/{root → src/views}/entry_form.xhtml +0 -0
  51. data/examples/blog/{root → src/views}/error.xhtml +0 -0
  52. data/examples/blog/{root → src/views}/index.xhtml +0 -0
  53. data/examples/blog/{root → src/views}/login.xhtml +0 -0
  54. data/examples/blog/{root → src/views}/recent_posts.xhtml +0 -0
  55. data/examples/blog/{root → src/views}/view_entry.xhtml +8 -0
  56. data/examples/blog/{root → src/views}/view_entry.xml +0 -0
  57. data/examples/blog/src/xsl/base.xsl +153 -0
  58. data/examples/blog/{root → src/xsl}/style.xsl +2 -2
  59. data/examples/no_xsl_blog/README +5 -1
  60. data/examples/no_xsl_blog/conf/apache.conf +2 -2
  61. data/examples/no_xsl_blog/conf/lhttpd.conf +2 -2
  62. data/examples/no_xsl_blog/lib/blog/model.rb +1 -1
  63. data/{lib/parts → examples/no_xsl_blog/lib}/content.rb +1 -11
  64. data/examples/no_xsl_blog/log/apache.error_log +405 -0
  65. data/examples/no_xsl_blog/{root → public}/comments.xhtml +0 -0
  66. data/examples/no_xsl_blog/{root → public}/entry_form.xhtml +0 -0
  67. data/examples/no_xsl_blog/{root → public}/fcgi.rb +0 -0
  68. data/examples/no_xsl_blog/{root → public}/index.xhtml +0 -0
  69. data/examples/no_xsl_blog/{root → public}/login.xhtml +0 -0
  70. data/examples/no_xsl_blog/{root → public}/m/bubbles.gif +0 -0
  71. data/examples/no_xsl_blog/{root → public}/m/comments_curve.gif +0 -0
  72. data/examples/no_xsl_blog/{root → public}/m/down.gif +0 -0
  73. data/examples/no_xsl_blog/{root → public}/m/footer_bg.gif +0 -0
  74. data/examples/no_xsl_blog/{root → public}/m/garrow.gif +0 -0
  75. data/examples/no_xsl_blog/{root → public}/m/gbull.gif +0 -0
  76. data/examples/no_xsl_blog/{root → public}/m/grbull.gif +0 -0
  77. data/examples/no_xsl_blog/{root → public}/m/h1_bg.gif +0 -0
  78. data/examples/no_xsl_blog/{root → public}/m/header_bg.gif +0 -0
  79. data/examples/no_xsl_blog/{root → public}/m/nitro.gif +0 -0
  80. data/examples/no_xsl_blog/{root → public}/m/obull.gif +0 -0
  81. data/examples/no_xsl_blog/{root → public}/m/page_bg.gif +0 -0
  82. data/examples/no_xsl_blog/{root → public}/m/rss.gif +0 -0
  83. data/examples/no_xsl_blog/{root → public}/m/side_title_bg.gif +0 -0
  84. data/examples/no_xsl_blog/{root → public}/m/sidebar_bg.gif +0 -0
  85. data/examples/no_xsl_blog/{root → public}/recent_posts.xhtml +0 -0
  86. data/examples/{blog/root → no_xsl_blog/public}/style.css +0 -0
  87. data/examples/no_xsl_blog/{root → public}/view_entry.xhtml +0 -0
  88. data/examples/no_xsl_blog/{root → public}/view_entry.xml +0 -0
  89. data/examples/tiny/conf/apache.conf +2 -2
  90. data/examples/tiny/log/apache.error_log +100 -0
  91. data/examples/tiny/{root → public}/fcgi.rb +0 -0
  92. data/examples/tiny/{root → public}/include.xhtml +0 -0
  93. data/examples/tiny/{root → public}/index.xhtml +0 -0
  94. data/{bin/proto/root/m → examples/tiny/public}/nitro.png +0 -0
  95. data/examples/tiny/{root → public}/upload.xhtml +0 -0
  96. data/examples/tiny/run.rb +1 -2
  97. data/examples/why_wiki/wiki.yml +1 -0
  98. data/install.rb +5 -2
  99. data/lib/nitro.rb +2 -6
  100. data/lib/nitro/adapters/fastcgi.rb +2 -2
  101. data/lib/nitro/adapters/webrick.rb +4 -4
  102. data/lib/nitro/conf.rb +5 -2
  103. data/lib/nitro/controller.rb +2 -2
  104. data/lib/nitro/dispatcher.rb +19 -8
  105. data/lib/nitro/mail.rb +252 -8
  106. data/lib/nitro/render.rb +24 -21
  107. data/lib/nitro/runner.rb +1 -1
  108. data/lib/nitro/scaffold.rb +2 -5
  109. data/lib/nitro/simple.rb +2 -1
  110. data/lib/nitro/template.rb +42 -2
  111. data/test/nitro/tc_controller.rb +9 -4
  112. data/test/nitro/tc_dispatcher.rb +4 -6
  113. data/test/nitro/tc_mail.rb +95 -0
  114. data/test/{root → public}/blog/list.xhtml +0 -0
  115. data/test/public/dummy_mailer/registration.xhtml +5 -0
  116. data/vendor/README +0 -1
  117. metadata +136 -181
  118. data/benchmark/og/bench.rb +0 -75
  119. data/benchmark/og/sqlite-no-prepare.1.txt +0 -13
  120. data/benchmark/og/sqlite-no-prepare.2.txt +0 -13
  121. data/benchmark/og/sqlite-prepare.1.txt +0 -13
  122. data/benchmark/og/sqlite-prepare.2.txt +0 -13
  123. data/bin/proto/README +0 -34
  124. data/bin/proto/conf/apache.conf +0 -1
  125. data/bin/proto/conf/app.conf.rb +0 -14
  126. data/bin/proto/conf/lhttpd.conf +0 -236
  127. data/bin/proto/ctl +0 -4
  128. data/bin/proto/lib/README +0 -5
  129. data/bin/proto/log/README +0 -3
  130. data/bin/proto/root/fcgi.rb +0 -6
  131. data/bin/proto/root/index.xhtml +0 -69
  132. data/bin/proto/root/style.css +0 -152
  133. data/bin/proto/root/style.xsl +0 -99
  134. data/doc/og_config.txt +0 -35
  135. data/doc/og_tutorial.txt +0 -595
  136. data/examples/og/README +0 -11
  137. data/examples/og/mock_example.rb +0 -50
  138. data/examples/og/mysql_to_psql.rb +0 -96
  139. data/examples/og/run.rb +0 -286
  140. data/examples/tiny/root/nitro.png +0 -0
  141. data/lib/glue.rb +0 -55
  142. data/lib/glue/array.rb +0 -61
  143. data/lib/glue/attribute.rb +0 -83
  144. data/lib/glue/cache.rb +0 -138
  145. data/lib/glue/flexob.rb +0 -12
  146. data/lib/glue/hash.rb +0 -122
  147. data/lib/glue/inflector.rb +0 -91
  148. data/lib/glue/logger.rb +0 -147
  149. data/lib/glue/misc.rb +0 -14
  150. data/lib/glue/mixins.rb +0 -36
  151. data/lib/glue/number.rb +0 -24
  152. data/lib/glue/object.rb +0 -32
  153. data/lib/glue/pool.rb +0 -60
  154. data/lib/glue/property.rb +0 -408
  155. data/lib/glue/string.rb +0 -162
  156. data/lib/glue/time.rb +0 -85
  157. data/lib/glue/validation.rb +0 -394
  158. data/lib/og.rb +0 -185
  159. data/lib/og/adapter.rb +0 -513
  160. data/lib/og/adapters/filesys.rb +0 -121
  161. data/lib/og/adapters/mysql.rb +0 -347
  162. data/lib/og/adapters/oracle.rb +0 -375
  163. data/lib/og/adapters/psql.rb +0 -273
  164. data/lib/og/adapters/sqlite.rb +0 -262
  165. data/lib/og/backend.rb +0 -297
  166. data/lib/og/connection.rb +0 -304
  167. data/lib/og/database.rb +0 -282
  168. data/lib/og/enchant.rb +0 -125
  169. data/lib/og/meta.rb +0 -373
  170. data/lib/og/mock.rb +0 -165
  171. data/lib/og/observer.rb +0 -53
  172. data/lib/og/typemacros.rb +0 -23
  173. data/lib/parts/README +0 -9
  174. data/test/glue/tc_attribute.rb +0 -22
  175. data/test/glue/tc_cache.rb +0 -45
  176. data/test/glue/tc_hash.rb +0 -38
  177. data/test/glue/tc_logger.rb +0 -39
  178. data/test/glue/tc_numbers.rb +0 -20
  179. data/test/glue/tc_property.rb +0 -89
  180. data/test/glue/tc_property_mixins.rb +0 -93
  181. data/test/glue/tc_property_type_checking.rb +0 -35
  182. data/test/glue/tc_strings.rb +0 -103
  183. data/test/glue/tc_validation.rb +0 -188
  184. data/test/og/tc_filesys.rb +0 -83
  185. data/test/og/tc_lifecycle.rb +0 -104
  186. data/test/og/tc_many_to_many.rb +0 -62
  187. data/test/og/tc_meta.rb +0 -55
  188. data/test/og/tc_observer.rb +0 -85
  189. data/test/og/tc_sqlite.rb +0 -87
  190. data/test/tc_og.rb +0 -355
  191. data/vendor/composite_sexp_processor.rb +0 -43
  192. data/vendor/parse_tree.rb +0 -745
  193. data/vendor/sexp_processor.rb +0 -453
@@ -1,453 +0,0 @@
1
-
2
- $TESTING = false unless defined? $TESTING
3
-
4
- class Object
5
-
6
- ##
7
- # deep_clone is the usual Marshalling hack to make a deep copy.
8
- # It is rather slow, so use it sparingly. Helps with debugging
9
- # SexpProcessors since you usually shift off sexps.
10
-
11
- def deep_clone
12
- Marshal.load(Marshal.dump(self))
13
- end
14
- end
15
-
16
- ##
17
- # Sexps are the basic storage mechanism of SexpProcessor. Sexps have
18
- # a +type+ (to be renamed +node_type+) which is the first element of
19
- # the Sexp. The type is used by SexpProcessor to determine whom to
20
- # dispatch the Sexp to for processing.
21
-
22
- class Sexp < Array # ZenTest FULL
23
-
24
- @@array_types = [ :array, :args, ]
25
-
26
- ##
27
- # Named positional parameters.
28
- # Use with +SexpProcessor.require_empty=false+.
29
- attr_accessor :accessors
30
-
31
- ##
32
- # Create a new Sexp containing +args+.
33
-
34
- def initialize(*args)
35
- @accessors = []
36
- super(args)
37
- end
38
-
39
- def self.from_array(a)
40
- ary = Array === a ? a : [a]
41
-
42
- result = self.new
43
-
44
- ary.each do |x|
45
- case x
46
- when Sexp
47
- result << x
48
- when Array
49
- result << self.from_array(x)
50
- else
51
- result << x
52
- end
53
- end
54
-
55
- result
56
- end
57
-
58
- ##
59
- # Returns true if the node_type is +array+ or +args+.
60
- #
61
- # REFACTOR: to TypedSexp - we only care when we have units.
62
-
63
- def array_type?
64
- type = self.first
65
- @@array_types.include? type
66
- end
67
-
68
- ##
69
- # Enumeratates the sexp yielding to +b+ when the node_type == +t+.
70
-
71
- def each_of_type(t, &b)
72
- each do | elem |
73
- if Sexp === elem then
74
- elem.each_of_type(t, &b)
75
- b.call(elem) if elem.first == t
76
- end
77
- end
78
- end
79
-
80
- ##
81
- # Replaces all elements whose node_type is +from+ with +to+. Used
82
- # only for the most trivial of rewrites.
83
-
84
- def find_and_replace_all(from, to)
85
- each_with_index do | elem, index |
86
- if Sexp === elem then
87
- elem.find_and_replace_all(from, to)
88
- else
89
- self[index] = to if elem == from
90
- end
91
- end
92
- end
93
-
94
- ##
95
- # Fancy-Schmancy method used to implement named positional accessors
96
- # via +accessors+.
97
- #
98
- # Example:
99
- #
100
- # class MyProcessor < SexpProcessor
101
- # def initialize
102
- # super
103
- # self.require_empty = false
104
- # self.sexp_accessors = {
105
- # :call => [:lhs, :name, :rhs]
106
- # }
107
- # ...
108
- # end
109
- #
110
- # def process_call(exp)
111
- # lhs = exp.lhs
112
- # name = exp.name
113
- # rhs = exp.rhs
114
- # ...
115
- # end
116
- # end
117
-
118
- def method_missing(meth, *a, &b)
119
- super unless @accessors.include? meth
120
-
121
- index = @accessors.index(meth) + 1 # skip type
122
- return self.at(index)
123
- end
124
-
125
- ##
126
- # Returns the Sexp without the node_type.
127
-
128
- def sexp_body
129
- self[1..-1]
130
- end
131
-
132
- ##
133
- # Returnes the bare bones structure of the sexp.
134
- # s(:a, :b, s(:c, :d), :e) => s(:a, s(:c))
135
-
136
- def structure
137
- result = self.class.new
138
- if Array === self.first then
139
- result = self.first.structure
140
- else
141
- result << self.shift
142
- self.grep(Array).each do |subexp|
143
- result << subexp.structure
144
- end
145
- end
146
- result
147
- end
148
-
149
- def ==(obj) # :nodoc:
150
- case obj
151
- when Sexp
152
- super
153
- else
154
- false
155
- end
156
- end
157
-
158
- def to_a # :nodoc:
159
- self.map { |o| Sexp === o ? o.to_a : o }
160
- end
161
-
162
- def inspect # :nodoc:
163
- sexp_str = self.map {|x|x.inspect}.join(', ')
164
- return "s(#{sexp_str})"
165
- end
166
-
167
- def pretty_print(q) # :nodoc:
168
- q.group(1, 's(', ')') do
169
- q.seplist(self) {|v| q.pp v }
170
- end
171
- end
172
-
173
- def to_s # :nodoc:
174
- inspect
175
- end
176
-
177
- ##
178
- # If run with debug, Sexp will raise if you shift on an empty
179
- # Sexp. Helps with debugging.
180
-
181
- def shift
182
- raise "I'm empty" if self.empty?
183
- super
184
- end if $DEBUG or $TESTING
185
-
186
- end
187
-
188
- ##
189
- # This is just a stupid shortcut to make indentation much cleaner.
190
-
191
- def s(*args)
192
- Sexp.new(*args)
193
- end
194
-
195
- ##
196
- # Raised by SexpProcessor if it sees a node type listed in its
197
- # unsupported list.
198
-
199
- class UnsupportedNodeError < SyntaxError; end
200
-
201
- ##
202
- # Raised by SexpProcessor if it is in strict mode and sees a node for
203
- # which there is no processor available.
204
-
205
- class UnknownNodeError < SyntaxError; end
206
-
207
- ##
208
- # Raised by SexpProcessor if a processor did not process every node in
209
- # a sexp and @require_empty is true.
210
-
211
- class NotEmptyError < SyntaxError; end
212
-
213
- ##
214
- # SexpProcessor provides a uniform interface to process Sexps.
215
- #
216
- # In order to create your own SexpProcessor subclass you'll need
217
- # to call super in the initialize method, then set any of the
218
- # Sexp flags you want to be different from the defaults.
219
- #
220
- # SexpProcessor uses a Sexp's type to determine which process method
221
- # to call in the subclass. For Sexp <code>s(:lit, 1)</code>
222
- # SexpProcessor will call #process_lit, if it is defined.
223
- #
224
- # You can also specify a default method to call for any Sexp types
225
- # without a process_<type> method or use the default processor provided to
226
- # skip over them.
227
- #
228
- # Here is a simple example:
229
- #
230
- # class MyProcessor < SexpProcessor
231
- # def initialize
232
- # super
233
- # self.strict = false
234
- # end
235
- #
236
- # def process_lit(exp)
237
- # val = exp.shift
238
- # return val
239
- # end
240
- # end
241
-
242
- class SexpProcessor
243
-
244
- ##
245
- # A default method to call if a process_<type> method is not found
246
- # for the Sexp type.
247
-
248
- attr_accessor :default_method
249
-
250
- ##
251
- # Emit a warning when the method in #default_method is called.
252
-
253
- attr_accessor :warn_on_default
254
-
255
- ##
256
- # Automatically shifts off the Sexp type before handing the
257
- # Sexp to process_<type>
258
-
259
- attr_accessor :auto_shift_type
260
-
261
- ##
262
- # An array that specifies node types that are unsupported by this
263
- # processor. SexpProcesor will raise UnsupportedNodeError if you try
264
- # to process one of those node types.
265
-
266
- attr_accessor :unsupported
267
-
268
- ##
269
- # Raise an exception if no process_<type> method is found for a Sexp.
270
-
271
- attr_accessor :strict
272
-
273
- ##
274
- # A Hash of Sexp types and Regexp.
275
- #
276
- # Print a debug message if the Sexp type matches the Hash key
277
- # and the Sexp's #inspect output matches the Regexp.
278
-
279
- attr_accessor :debug
280
-
281
- ##
282
- # Expected result class
283
-
284
- attr_accessor :expected
285
-
286
- ##
287
- # Raise an exception if the Sexp is not empty after processing
288
-
289
- attr_accessor :require_empty
290
-
291
- ##
292
- # Adds accessor methods to the Sexp
293
-
294
- attr_accessor :sexp_accessors
295
-
296
- ##
297
- # Creates a new SexpProcessor. Use super to invoke this
298
- # initializer from SexpProcessor subclasses, then use the
299
- # attributes above to customize the functionality of the
300
- # SexpProcessor
301
-
302
- def initialize
303
- @collection = []
304
- @default_method = nil
305
- @warn_on_default = true
306
- @auto_shift_type = false
307
- @strict = false
308
- @unsupported = []
309
- @debug = {}
310
- @expected = Sexp
311
- @require_empty = true
312
- @sexp_accessors = {}
313
-
314
- # we do this on an instance basis so we can subclass it for
315
- # different processors.
316
- @processors = {}
317
- @rewriters = {}
318
-
319
- public_methods.each do |name|
320
- case name
321
- when /^process_(.*)/ then
322
- @processors[$1.intern] = name.intern
323
- when /^rewrite_(.*)/ then
324
- @rewriters[$1.intern] = name.intern
325
- end
326
- end
327
- end
328
-
329
- ##
330
- # Default Sexp processor. Invokes process_<type> methods matching
331
- # the Sexp type given. Performs additional checks as specified by
332
- # the initializer.
333
-
334
- def process(exp)
335
- return nil if exp.nil?
336
-
337
- exp_orig = exp.deep_clone if $DEBUG
338
- result = self.expected.new
339
-
340
- type = exp.first
341
-
342
- if @debug.include? type then
343
- str = exp.inspect
344
- puts "// DEBUG: #{str}" if str =~ @debug[type]
345
- end
346
-
347
- if Sexp === exp then
348
- if @sexp_accessors.include? type then
349
- exp.accessors = @sexp_accessors[type]
350
- else
351
- exp.accessors = [] # clean out accessor list in case it changed
352
- end
353
- end
354
-
355
- raise UnsupportedNodeError, "'#{type}' is not a supported node type" if @unsupported.include? type
356
-
357
- # do a pass through the rewriter first, if any, reassign back to exp
358
- meth = @rewriters[type]
359
- if meth then
360
- new_exp = self.send(meth, exp)
361
- # REFACTOR: duplicated from below
362
- if @require_empty and not exp.empty? then
363
- msg = "exp not empty after #{self.class}.#{meth} on #{exp.inspect}"
364
- if $DEBUG then
365
- msg += " from #{exp_orig.inspect}"
366
- end
367
- raise NotEmptyError, msg
368
- end
369
- exp = new_exp
370
- end
371
-
372
- # now do a pass with the real processor (or generic
373
- meth = @processors[type] || @default_method
374
- if meth then
375
-
376
- if @warn_on_default and meth == @default_method then
377
- $stderr.puts "WARNING: Using default method #{meth} for #{type}"
378
- end
379
-
380
- exp.shift if @auto_shift_type and meth != @default_method
381
-
382
- result = self.send(meth, exp)
383
- raise TypeError, "Result must be a #{@expected}, was #{result.class}:#{result.inspect}" unless @expected === result
384
-
385
- if @require_empty and not exp.empty? then
386
- msg = "exp not empty after #{self.class}.#{meth} on #{exp.inspect}"
387
- if $DEBUG then
388
- msg += " from #{exp_orig.inspect}"
389
- end
390
- raise NotEmptyError, msg
391
- end
392
- else
393
- unless @strict then
394
- until exp.empty? do
395
- sub_exp = exp.shift
396
- sub_result = nil
397
- if Array === sub_exp then
398
- sub_result = process(sub_exp)
399
- raise "Result is a bad type" unless Array === sub_exp
400
- raise "Result does not have a type in front: #{sub_exp.inspect}" unless Symbol === sub_exp.first unless sub_exp.empty?
401
- else
402
- sub_result = sub_exp
403
- end
404
- result << sub_result
405
- end
406
-
407
- # NOTE: this is costly, but we are in the generic processor
408
- # so we shouldn't hit it too much with RubyToC stuff at least.
409
- #if Sexp === exp and not exp.sexp_type.nil? then
410
- begin
411
- result.sexp_type = exp.sexp_type
412
- rescue Exception
413
- # nothing to do, on purpose
414
- end
415
- else
416
- raise UnknownNodeError, "Bug! Unknown type #{type.inspect} to #{self.class}"
417
- end
418
- end
419
- result
420
- end
421
-
422
- def generate # :nodoc:
423
- raise "not implemented yet"
424
- end
425
-
426
- ##
427
- # Raises unless the Sexp type for +list+ matches +typ+
428
-
429
- def assert_type(list, typ)
430
- raise TypeError, "Expected type #{typ.inspect} in #{list.inspect}" if
431
- list.first != typ
432
- end
433
-
434
- ##
435
- # A fairly generic processor for a dummy node. Dummy nodes are used
436
- # when your processor is doing a complicated rewrite that replaces
437
- # the current sexp with multiple sexps.
438
- #
439
- # Bogus Example:
440
- #
441
- # def process_something(exp)
442
- # return s(:dummy, process(exp), s(:extra, 42))
443
- # end
444
-
445
- def process_dummy(exp)
446
- result = @expected.new(:dummy)
447
- until exp.empty? do
448
- result << self.process(exp.shift)
449
- end
450
- result
451
- end
452
- end
453
-