public
Rubygem
Description: Merb Core: All you need. None you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/wycats/merb-core.git
Search Repo:
Redo Merb's inheritable_accessors so that they have correct semantics, 
then redo everything that uses inheritable_accessors so they don't have to 
hack around the bad semantics.
wycats (author)
Fri Jun 27 21:36:13 -0700 2008
commit  b5e42a1d7e1000516b7799bbc35efe442bbea6c9
tree    b23327b14d1f1e72fc1b368ecae8f2670f8aa6c1
parent  8a2e4d1daf96a3beaed151d643d497e8a52cae1f
...
2
3
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
6
7
 
8
9
 
10
11
12
 
13
14
 
15
16
 
 
17
18
 
19
20
 
 
 
 
 
 
 
 
21
22
23
24
25
 
 
26
27
 
28
29
30
...
46
47
48
 
 
 
 
49
50
51
52
53
54
55
56
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
72
73
74
 
75
76
 
77
78
 
79
80
81
 
82
83
 
84
85
86
87
88
89
90
91
92
93
94
 
 
95
96
97
 
98
99
100
101
...
117
118
119
120
121
122
123
124
125
126
127
128
129
 
 
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
0
@@ -2,29 +2,100 @@ require "rubygems"
0
 require "erubis"
0
 
0
 module Erubis
0
+ module Basic::Converter
0
+ def add_tailchar(src, tailchar)
0
+ end
0
+
0
+ def convert_input(src, input)
0
+ pat = @pattern
0
+ regexp = pat.nil? || pat == '<% %>' ? DEFAULT_REGEXP : pattern_regexp(pat)
0
+ pos = 0
0
+ is_bol = true # is beginning of line
0
+ input.scan(regexp) do |indicator, code, tailch, rspace|
0
+ match = Regexp.last_match()
0
+ len = match.begin(0) - pos
0
+ text = input[pos, len]
0
+ pos = match.end(0)
0
+ ch = indicator ? indicator[0] : nil
0
+ lspace = ch == ?= ? nil : detect_spaces_at_bol(text, is_bol)
0
+ is_bol = rspace ? true : false
0
+ add_text(src, text) if text && !text.empty?
0
+ ## * when '<%= %>', do nothing
0
+ ## * when '<% %>' or '<%# %>', delete spaces iff only spaces are around '<% %>'
0
+ if ch == ?= # <%= %>
0
+ rspace = nil if tailch && !tailch.empty?
0
+ add_text(src, lspace) if lspace
0
+ add_expr(src, code, indicator)
0
+ add_text(src, rspace) if rspace
0
+ elsif ch == ?\# # <%# %>
0
+ n = code.count("\n") + (rspace ? 1 : 0)
0
+ if @trim && lspace && rspace
0
+ add_stmt(src, "\n" * n)
0
+ else
0
+ add_text(src, lspace) if lspace
0
+ add_stmt(src, "\n" * n)
0
+ add_text(src, rspace) if rspace
0
+ end
0
+ elsif ch == ?% # <%% %>
0
+ s = "#{lspace}#{@prefix||='<%'}#{code}#{tailch}#{@postfix||='%>'}#{rspace}"
0
+ add_text(src, s)
0
+ else # <% %>
0
+ if @trim && lspace && rspace
0
+ if respond_to?(:add_stmt2)
0
+ add_stmt2(src, "#{lspace}#{code}#{rspace}", tailch)
0
+ else
0
+ add_stmt(src, "#{lspace}#{code}#{rspace}")
0
+ end
0
+ else
0
+ add_text(src, lspace) if lspace
0
+ if respond_to?(:add_stmt2)
0
+ add_stmt2(src, code, tailch)
0
+ else
0
+ add_stmt(src, code)
0
+ end
0
+ add_text(src, rspace) if rspace
0
+ end
0
+ end
0
+ end
0
+ #rest = $' || input # ruby1.8
0
+ rest = pos == 0 ? input : input[pos..-1] # ruby1.9
0
+ add_text(src, rest)
0
+ end
0
+
0
+ end
0
+
0
   module BlockAwareEnhancer
0
     def add_preamble(src)
0
       src << "_old_buf, @_erb_buf = @_erb_buf, ''; "
0
+ src << "@_engine = 'erb'; "
0
     end
0
-
0
+
0
     def add_postamble(src)
0
       src << "\n" unless src[-1] == ?\n
0
- src << "_ret = @_erb_buf; @_erb_buf = _old_buf; _ret.to_s\n"
0
+ src << "_ret = @_erb_buf; @_erb_buf = _old_buf; _ret.to_s;\n"
0
     end
0
-
0
+
0
     def add_text(src, text)
0
- src << " @_erb_buf << '" << text << "'; "
0
+ p escape_text(text)
0
+ src << " @_erb_buf.concat('" << escape_text(text) << "'); "
0
     end
0
-
0
+
0
     def add_expr_escaped(src, code)
0
- src << ' @_erb_buf << ' << escaped_expr(code) << ';'
0
+ src << ' @_erb_buf.concat(' << escaped_expr(code) << ');'
0
+ end
0
+
0
+ def add_stmt2(src, code, tailch)
0
+ #src << code << ';'
0
+ src << code
0
+ src << " ).to_s; " if tailch == "="
0
+ src << ';' unless code[-1] == ?\n
0
     end
0
     
0
     def add_expr_literal(src, code)
0
- unless code =~ /(do|\{)(\s*|[^|]*|)?\s*$/
0
- src << ' @_erb_buf << (' << code << ').to_s;'
0
+ if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/
0
+ src << ' @_erb_buf.concat( ' << code << "; "
0
       else
0
- src << ' @_erb_buf << ' << code << "; "
0
+ src << ' @_erb_buf.concat((' << code << ').to_s);'
0
       end
0
     end
0
   end
0
@@ -46,11 +117,67 @@ class Context
0
   def hello
0
     "Hello"
0
   end
0
+
0
+ def hello2
0
+ "Hello"
0
+ end
0
 
0
   def helper(&blk)
0
     "<tag>#{capture(&blk)}</tag>"
0
   end
0
 end
0
 
0
-puts Erubis::BlockAwareEruby.new("Begin: <%= helper do %>Hello<% end %><% 3.times do %>X<% end %><%= hello %>").src
0
-p Erubis::BlockAwareEruby.new.process("Begin: <%= helper do %>Hello<% end %><% 3.times do %>X<% end %><%= hello %>", Context.new)
0
\ No newline at end of file
0
+# puts Erubis::BlockAwareEruby.new("Begin: <%= helper do %>Hello<% 3.times do %>X<% end %><% end %><%= hello %>").src
0
+# p Erubis::BlockAwareEruby.new.process("Begin: <%= helper do %>Hello<%= 3.times do %>X<% end %><% end %><%= hello %>", Context.new)
0
+
0
+def form_for(bar)
0
+ bar.to_s
0
+end
0
+
0
+class Foo
0
+end
0
+
0
+# _old_verbose, $VERBOSE = $VERBOSE, nil
0
+# Erubis::BlockAwareEruby.new("<%= form_for :foo do %>Hello<% end %>").def_method(Foo, :stuffs)
0
+# $VERBOSE = _old_verbose
0
+# require "parse_tree"
0
+require "ruby_parser"
0
+require "ruby2ruby"
0
+
0
+text = <<-END
0
+Pre. <p><%= form_for :field do %>
0
+ Capturing
0
+<% end =%>
0
+
0
+<% if true %>Hello<% end %>
0
+<% if false %>Goodbye<% end %>
0
+END
0
+
0
+p Erubis::BlockAwareEruby.new(text).src
0
+p Erubis::BlockAwareEruby.new.process(text)
0
+
0
+__END__
0
+puts Erubis::BlockAwareEruby.new(<<-TEMPLATE).src
0
+<ul id="nav">
0
+ <% @nav_items = [] %>
0
+ <% @nav_items << nav_item('Home', url(:root)) %>
0
+ <% @nav_items << nav_item('Messaging', url(:new_message)) if current_user.has_permission?('message.send') %>
0
+ <% if current_user.has_permission?('schedule.power_user') %>
0
+ <% @nav_items << "<li>\#{link_to('Schedule', 'https://belpark.net/schedule/pwrusr/', :popup => true)}</li>" %>
0
+ <% elsif current_user.has_permission?('schedule.view') %>
0
+ <% @nav_items << nav_item('Schedule', 'https://belpark.net/schedule/user/calendar.php') %>
0
+ <% end %>
0
+ <% if current_user.emails.exists?(["emails.address LIKE ?", '%@belpark.net']) %>
0
+ <% @nav_items << "<li>\#{link_to('Email', 'https://belpark.net/dwmail/', :popup => true)}</li>" %>
0
+ <% end %>
0
+ <% @nav_items << nav_item('Directory', url(:users)) if current_user.has_permission?('user.view') %>
0
+ <%= @nav_items.join('<li class="divider">|</li>') %>
0
+</ul>
0
+<ul id="nav2">
0
+ <% @nav_items = [] %>
0
+ <% @nav_items << "<li>\#{current_user.full_name}</li>" %>
0
+ <% @nav_items << "<li>\#{link_to('Settings', url(:edit_user, current_user.id))}</li>" if current_user.has_permission?('user.modify_self') %>
0
+ <% @nav_items << "<li>\#{link_to 'Log Out', url(:logout), :id => 'logout'}</li>" %>
0
+ <%= @nav_items.join('<li class="divider">|</li>') %>
0
+</ul>
0
+TEMPLATE
0
\ No newline at end of file
...
81
82
83
84
85
 
 
86
87
88
...
144
145
146
 
 
 
 
 
 
 
 
 
147
148
149
150
151
152
153
 
154
155
156
...
158
159
160
161
 
162
163
164
...
81
82
83
 
 
84
85
86
87
88
...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
 
 
161
162
163
164
...
166
167
168
 
169
170
171
172
0
@@ -81,8 +81,8 @@ class Merb::AbstractController
0
   include Merb::RenderMixin
0
   include Merb::InlineTemplates
0
   
0
- class_inheritable_accessor :_layout, :_template_root
0
- class_inheritable_array :_before_filters, :_after_filters
0
+ class_inheritable_accessor :_layout, :_template_root, :template_roots
0
+ class_inheritable_accessor :_before_filters, :_after_filters
0
   
0
   FILTER_OPTIONS = [:only, :exclude, :if, :unless, :with]
0
 
0
@@ -144,13 +144,21 @@ class Merb::AbstractController
0
     template
0
   end
0
 
0
+ def self._template_root=(root)
0
+ @_template_root = root
0
+ _reset_template_roots
0
+ end
0
+
0
+ def self._reset_template_roots
0
+ self.template_roots = [[self._template_root, :_template_location]]
0
+ end
0
+
0
   # ==== Returns
0
   # roots<Array[Array]>::
0
   # Template roots as pairs of template root path and template location
0
   # method.
0
   def self._template_roots
0
- read_inheritable_attribute(:template_roots) ||
0
- write_inheritable_attribute(:template_roots, [[self._template_root, :_template_location]])
0
+ self.template_roots || _reset_template_roots
0
   end
0
 
0
   # ==== Parameters
0
@@ -158,7 +166,7 @@ class Merb::AbstractController
0
   # Template roots as pairs of template root path and template location
0
   # method.
0
   def self._template_roots=(roots)
0
- write_inheritable_attribute(:template_roots, roots)
0
+ self.template_roots = roots
0
   end
0
   
0
   cattr_accessor :_abstract_subclasses, :_template_path_cache
...
1
2
3
 
 
 
4
5
6
...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
1
2
3
4
5
6
7
8
9
...
78
79
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
82
83
0
@@ -1,6 +1,9 @@
0
 class Merb::Controller < Merb::AbstractController
0
 
0
   class_inheritable_accessor :_hidden_actions, :_shown_actions
0
+ self._hidden_actions ||= []
0
+ self._shown_actions ||= []
0
+
0
   cattr_accessor :_subclasses, :_session_id_key, :_session_secret_key, :_session_expiry, :_session_cookie_domain
0
   self._subclasses = Set.new
0
 
0
@@ -75,26 +78,6 @@ class Merb::Controller < Merb::AbstractController
0
       self._shown_actions = self._shown_actions | names.map {|n| n.to_s}
0
     end
0
 
0
- # This list of actions that should not be callable.
0
- #
0
- # ==== Returns
0
- # Array[String]:: An array of actions that should not be dispatchable.
0
- def _hidden_actions
0
- actions = read_inheritable_attribute(:_hidden_actions)
0
- actions ? actions : write_inheritable_attribute(:_hidden_actions, [])
0
- end
0
-
0
- # This list of actions that should be callable.
0
- #
0
- # ==== Returns
0
- # Array[String]::
0
- # An array of actions that should be dispatched to even if they would not
0
- # otherwise be.
0
- def _shown_actions
0
- actions = read_inheritable_attribute(:_shown_actions)
0
- actions ? actions : write_inheritable_attribute(:_shown_actions, [])
0
- end
0
-
0
     # The list of actions that are callable, after taking defaults,
0
     # _hidden_actions and _shown_actions into consideration. It is calculated
0
     # once, the first time an action is dispatched for this controller.
...
105
106
107
108
 
109
110
111
...
105
106
107
 
108
109
110
111
0
@@ -105,7 +105,7 @@ module Merb::RenderMixin
0
 
0
       template_method, template_location =
0
         _template_for(thing, content_type, controller_name, opts[:template])
0
-
0
+
0
       # Raise an error if there's no template
0
       unless template_method && self.respond_to?(template_method)
0
         template_files = Merb::Template.template_extensions.map { |ext| "#{template_location}.#{ext}" }
...
134
135
136
137
138
139
 
140
141
142
...
214
215
216
217
218
219
220
...
240
241
242
243
244
245
 
 
246
247
248
...
134
135
136
 
 
 
137
138
139
140
...
212
213
214
 
215
216
217
...
237
238
239
 
 
 
240
241
242
243
244
0
@@ -134,9 +134,7 @@ module Merb
0
       #---
0
       # @public
0
       def provides(*formats)
0
- formats.each do |fmt|
0
- self.class_provided_formats << fmt unless class_provided_formats.include?(fmt)
0
- end
0
+ self.class_provided_formats |= formats
0
       end
0
       
0
       # This class should only provide the formats listed here, despite any
0
@@ -214,7 +212,6 @@ module Merb
0
       if @_content_type
0
         raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set"
0
       end
0
- @_provided_formats = []
0
       provides(*formats)
0
     end
0
     alias :_provided_formats= :_set_provided_formats
0
@@ -240,9 +237,8 @@ module Merb
0
       if @_content_type
0
         raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set"
0
       end
0
- formats.each do |fmt|
0
- _provided_formats << fmt unless _provided_formats.include?(fmt)
0
- end
0
+ @_provided_formats ||= []
0
+ @_provided_formats |= formats
0
     end
0
 
0
     # Sets list of provided formats for this particular request. Usually used
...
19
20
21
22
23
24
25
...
39
40
41
42
 
43
44
45
...
51
52
53
54
 
55
56
57
...
65
66
67
68
 
69
70
71
...
76
77
78
79
 
80
81
82
...
110
111
112
113
114
115
116
117
118
119
120
121
122
123
 
 
 
 
 
 
 
 
 
 
124
125
 
 
 
 
 
 
 
 
126
127
128
 
129
130
131
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
 
 
 
 
 
 
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
 
 
 
213
214
215
216
217
 
218
219
220
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
...
19
20
21
 
22
23
24
...
38
39
40
 
41
42
43
44
...
50
51
52
 
53
54
55
56
...
64
65
66
 
67
68
69
70
...
75
76
77
 
78
79
80
81
...
109
110
111
 
 
 
 
 
 
 
 
 
 
 
112
113
114
115
116
117
118
119
120
121
122
 
123
124
125
126
127
128
129
130
131
132
 
133
134
135
136
...
143
144
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
147
148
149
150
151
152
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
155
156
157
158
159
160
 
161
162
163
164
...
172
173
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
0
@@ -19,7 +19,6 @@
0
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
0
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0
 
0
-
0
 # Allows attributes to be shared within an inheritance hierarchy, but where
0
 # each descendant gets a copy of their parents' attributes, instead of just a
0
 # pointer to the same. This means that the child can add elements to, for
0
@@ -39,7 +38,7 @@ class Class
0
   def cattr_reader(*syms)
0
     syms.flatten.each do |sym|
0
       next if sym.is_a?(Hash)
0
- class_eval(<<-EOS, __FILE__, __LINE__)
0
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
0
         unless defined? @@#{sym}
0
           @@#{sym} = nil
0
         end
0
@@ -51,7 +50,7 @@ class Class
0
         def #{sym}
0
           @@#{sym}
0
         end
0
- EOS
0
+ RUBY
0
     end
0
   end
0
 
0
@@ -65,7 +64,7 @@ class Class
0
   def cattr_writer(*syms)
0
     options = syms.last.is_a?(Hash) ? syms.pop : {}
0
     syms.flatten.each do |sym|
0
- class_eval(<<-RUBY, __FILE__, __LINE__)
0
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
0
         unless defined? @@#{sym}
0
           @@#{sym} = nil
0
         end
0
@@ -76,7 +75,7 @@ class Class
0
       RUBY
0
       
0
       unless options[:instance_writer] == false
0
- class_eval(<<-RUBY, __FILE__, __LINE__)
0
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
0
           def #{sym}=(obj)
0
             @@#{sym} = obj
0
           end
0
@@ -110,22 +109,28 @@ class Class
0
   # (error out or do the same as other methods above) instead of silently
0
   # moving on). In particular, this makes the return value of this function
0
   # less useful.
0
- def class_inheritable_reader(*syms)
0
- syms.each do |sym|
0
- next if sym.is_a?(Hash)
0
- class_eval <<-EOS, __FILE__, __LINE__
0
-
0
- def self.#{sym}
0
- read_inheritable_attribute(:#{sym})
0
- end
0
-
0
- def #{sym}
0
- self.class.#{sym}
0
+ def class_inheritable_reader(*ivars)
0
+ instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
0
+
0
+ ivars.each do |ivar|
0
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
0
+ def self.#{ivar}
0
+ return @#{ivar} if self == #{self} || defined?(@#{ivar})
0
+ ivar = superclass.#{ivar}
0
+ return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
0
+ @#{ivar} = ivar ? ivar.dup : ivar
0
         end
0
- EOS
0
+ RUBY
0
+ unless instance_reader == false
0
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
0
+ def #{ivar}
0
+ self.class.#{ivar}
0
+ end
0
+ RUBY
0
+ end
0
     end
0
   end
0
-
0
+
0
   # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
0
   # each subclass has a copy of parent's attribute.
0
   #
0
@@ -138,83 +143,22 @@ class Class
0
   #
0
   # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
0
   # class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
0
- def class_inheritable_writer(*syms)
0
- options = syms.last.is_a?(Hash) ? syms.pop : {}
0
- syms.each do |sym|
0
- class_eval(<<-RUBY, __FILE__, __LINE__)
0
- def self.#{sym}=(obj)
0
- write_inheritable_attribute(:#{sym}, obj)
0
- end
0
- RUBY
0
- unless options[:instance_writer] == false
0
- class_eval <<-RUBY, __FILE__, __LINE__
0
- def #{sym}=(obj)
0
- self.class.#{sym} = obj
0
- end
0
- RUBY
0
- end
0
- end
0
- end
0
-
0
- # Defines class-level inheritable array writer. Arrays are available to subclasses,
0
- # each subclass has a copy of parent's array. Difference between other inheritable
0
- # attributes is that array is recreated every time it is written.
0
- #
0
- # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of array attribute
0
- # names to define inheritable writer for.
0
- # @option syms :instance_writer<Boolean> if true, instance-level inheritable array
0
- # attribute writer is defined.
0
- # @return <Array[#to_s]> An array of the attributes that were made into inheritable
0
- # array writers.
0
- #
0
- # @api public
0
- def class_inheritable_array_writer(*syms)
0
- options = syms.last.is_a?(Hash) ? syms.pop : {}
0
- syms.each do |sym|
0
- class_eval(<<-RUBY, __FILE__, __LINE__)
0
- def self.#{sym}=(obj)
0
- write_inheritable_array(:#{sym}, obj)
0
+ def class_inheritable_writer(*ivars)
0
+ instance_writer = ivars.pop[:instance_writer] if ivars.last.is_a?(Hash)
0
+ ivars.each do |ivar|
0
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
0
+ def self.#{ivar}=(obj)
0
+ @#{ivar} = obj
0
         end
0
       RUBY
0
- unless options[:instance_writer] == false
0
- class_eval(<<-RUBY, __FILE__, __LINE__)
0
- def #{sym}=(obj)
0
- self.class.#{sym} = obj
0
- end
0
- RUBY
0
- end
0
- end
0
- end
0
-
0
- # Defines class-level inheritable hash writer. Hashs are available to subclasses,
0
- # each subclass has a copy of parent's hash. Difference between other inheritable
0
- # attributes is that hash is recreated every time it is written.
0
- #
0
- # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]>:: Array of hash
0
- # attribute names to define inheritable writer for.
0
- # @option syms :instance_writer<Boolean>:: if true, instance-level inheritable hash
0
- # attribute writer is defined.
0
- # @return <Array[#to_s]> An Array of attributes turned into hash_writers.
0
- #
0
- # @api public
0
- def class_inheritable_hash_writer(*syms)
0
- options = syms.last.is_a?(Hash) ? syms.pop : {}
0
- syms.each do |sym|
0
- class_eval(<<-RUBY, __FILE__, __LINE__)
0
- def self.#{sym}=(obj)
0
- write_inheritable_hash(:#{sym}, obj)
0
- end
0
- RUBY
0
- unless options[:instance_writer] == false
0
- class_eval(<<-RUBY, __FILE__, __LINE__)
0
- def #{sym}=(obj)
0
- self.class.#{sym} = obj
0
- end
0
+ unless instance_writer == false
0
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
0
+ def #{ivar}=(obj) self.class.#{ivar} = obj end
0
         RUBY
0
       end
0
     end
0
   end
0
-
0
+
0
   # Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
0
   # each subclass has a copy of parent's attribute.
0
   #
0
@@ -228,136 +172,4 @@ class Class
0
     class_inheritable_reader(*syms)
0
     class_inheritable_writer(*syms)
0
   end
0
-
0
- # Defines class-level inheritable array accessor. Arrays are available to subclasses,
0
- # each subclass has a copy of parent's array. Difference between other inheritable
0
- # attributes is that array is recreated every time it is written.
0
- #
0
- # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of array attribute
0
- # names to define inheritable accessor for.
0
- # @option syms :instance_writer<Boolean> if true, instance-level inheritable array
0
- # attribute writer is defined.
0
- # @return <Array[#to_s]> An Array of attributes turned into inheritable arrays.
0
- #
0
- # @api public
0
- def class_inheritable_array(*syms)
0
- class_inheritable_reader(*syms)
0
- class_inheritable_array_writer(*syms)
0
- end
0
-
0
- # Defines class-level inheritable hash accessor. Hashs are available to subclasses,
0
- # each subclass has a copy of parent's hash. Difference between other inheritable
0
- # attributes is that hash is recreated every time it is written.
0
- #
0
- # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of hash attribute
0
- # names to define inheritable accessor for.
0
- # @option syms :instance_writer<Boolean> if true, instance-level inheritable hash
0
- # attribute writer is defined.
0
- # @return <Array[#to_s]> An Array of attributes turned into inheritable hashes.
0
- def class_inheritable_hash(*syms)
0
- class_inheritable_reader(*syms)
0
- class_inheritable_hash_writer(*syms)
0
- end
0
-
0
- # @return <Hash> inheritable attributes hash or it's default value, new frozen Hash.
0
- #
0
- # @api private
0
- def inheritable_attributes
0
- @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
0
- end
0
-
0
- # Sets the attribute which copy is available to subclasses.
0
- #
0
- # @param key<#to_s> inheritable attribute name
0
- # @param value<not(Array, Hash)> value of inheritable attribute
0
- # @return <not(Array, Hash)> the value that was set
0
- #
0
- # @api private
0
- #
0
- # @note
0
- # If inheritable attributes storage has it's default value,
0
- # a new frozen hash, it is set to new Hash that is not frozen.
0
- def write_inheritable_attribute(key, value)
0
- if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
0
- @inheritable_attributes = {}
0
- end
0
- inheritable_attributes[key] = value
0
- end
0
-
0
- # Sets the array attribute which copy is available to subclasses.
0
- #
0
- # @param key<#to_s> inheritable attribute name
0
- # @param elements<Array> value of inheritable attribute
0
- # @return <Array> the Array that was set
0
- #
0
- # @api private
0
- #
0
- # @note
0
- # Inheritable array is re-created on each write.
0
- def write_inheritable_array(key, elements)
0
- write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
0
- write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
0
- end
0
-
0
- # Sets the hash attribute which copy is available to subclasses.
0
- #
0
- # @param key<#to_s> inheritable attribute name
0
- # @param value<Hash> value of inheritable attribute
0
- # @return <Hash> the new hash that resulted from merging the new values
0
- # with the inherited values.
0
- #
0
- # @api private
0
- #
0
- # @note
0
- # Inheritable hash is re-created on each write.
0
- def write_inheritable_hash(key, hash)
0
- write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
0
- write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
0
- end
0
-
0
- # Reads value of inheritable attributes.
0
- #
0
- # @param key<#to_s> the key of the attribute to read
0
- # @return <Object>
0
- # Inheritable attribute value. Subclasses store copies of values.
0
- #
0
- # @api private
0
- def read_inheritable_attribute(key)
0
- inheritable_attributes[key]
0
- end
0
-
0
- # Resets inheritable attributes.
0
- #
0
- # @return <Object> the empty inheritable attributes. By default, this
0
- # is a frozen, empty Hash. You can override this for a class by defining
0
- # EMPTY_INHERITABLE_ATTRIBUTES
0
- #
0
- # @api private
0
- #
0
- # @todo do we need this?
0
- def reset_inheritable_attributes
0
- @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
0
- end
0
-
0
- private
0
- # Prevent this constant from being created multiple times
0
- EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
0
-
0
- # @todo document this
0
- def inherited_with_inheritable_attributes(child)
0
- inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
0
-
0
- if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
0
- new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
0
- else
0
- new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
0
- memo.update(key => ((value.is_a?(Module) ? value : value.dup) rescue value))
0
- end
0
- end
0
-
0
- child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
0
- end
0
-
0
- alias inherited_without_inheritable_attributes inherited
0
- alias inherited inherited_with_inheritable_attributes
0
 end

Comments

    No one has commented yet.