csd 0.0.15 → 0.0.16

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 (256) hide show
  1. data/.gitignore +1 -0
  2. data/COPYING +367 -0
  3. data/Rakefile +10 -10
  4. data/VERSION +1 -1
  5. data/bin/ai +19 -0
  6. data/csd.gemspec +257 -35
  7. data/lib/active_support.rb +75 -0
  8. data/lib/active_support/all.rb +3 -0
  9. data/lib/active_support/backtrace_cleaner.rb +94 -0
  10. data/lib/active_support/base64.rb +42 -0
  11. data/lib/active_support/basic_object.rb +21 -0
  12. data/lib/active_support/benchmarkable.rb +60 -0
  13. data/lib/active_support/buffered_logger.rb +132 -0
  14. data/lib/active_support/builder.rb +6 -0
  15. data/lib/active_support/cache.rb +626 -0
  16. data/lib/active_support/cache/compressed_mem_cache_store.rb +13 -0
  17. data/lib/active_support/cache/file_store.rb +188 -0
  18. data/lib/active_support/cache/mem_cache_store.rb +191 -0
  19. data/lib/active_support/cache/memory_store.rb +159 -0
  20. data/lib/active_support/cache/strategy/local_cache.rb +164 -0
  21. data/lib/active_support/cache/synchronized_memory_store.rb +11 -0
  22. data/lib/active_support/callbacks.rb +600 -0
  23. data/lib/active_support/concern.rb +29 -0
  24. data/lib/active_support/configurable.rb +36 -0
  25. data/lib/active_support/core_ext.rb +3 -0
  26. data/lib/active_support/core_ext/array.rb +7 -0
  27. data/lib/active_support/core_ext/array/access.rb +46 -0
  28. data/lib/active_support/core_ext/array/conversions.rb +164 -0
  29. data/lib/active_support/core_ext/array/extract_options.rb +29 -0
  30. data/lib/active_support/core_ext/array/grouping.rb +100 -0
  31. data/lib/active_support/core_ext/array/random_access.rb +20 -0
  32. data/lib/active_support/core_ext/array/uniq_by.rb +17 -0
  33. data/lib/active_support/core_ext/array/wrap.rb +22 -0
  34. data/lib/active_support/core_ext/benchmark.rb +7 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +27 -0
  37. data/lib/active_support/core_ext/cgi.rb +1 -0
  38. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +19 -0
  39. data/lib/active_support/core_ext/class.rb +4 -0
  40. data/lib/active_support/core_ext/class/attribute.rb +67 -0
  41. data/lib/active_support/core_ext/class/attribute_accessors.rb +63 -0
  42. data/lib/active_support/core_ext/class/delegating_attributes.rb +44 -0
  43. data/lib/active_support/core_ext/class/inheritable_attributes.rb +232 -0
  44. data/lib/active_support/core_ext/class/subclasses.rb +55 -0
  45. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  46. data/lib/active_support/core_ext/date/calculations.rb +240 -0
  47. data/lib/active_support/core_ext/date/conversions.rb +99 -0
  48. data/lib/active_support/core_ext/date/freeze.rb +31 -0
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +13 -0
  50. data/lib/active_support/core_ext/date_time/calculations.rb +113 -0
  51. data/lib/active_support/core_ext/date_time/conversions.rb +102 -0
  52. data/lib/active_support/core_ext/date_time/zones.rb +17 -0
  53. data/lib/active_support/core_ext/enumerable.rb +119 -0
  54. data/lib/active_support/core_ext/exception.rb +3 -0
  55. data/lib/active_support/core_ext/file.rb +2 -0
  56. data/lib/active_support/core_ext/file/atomic.rb +41 -0
  57. data/lib/active_support/core_ext/file/path.rb +5 -0
  58. data/lib/active_support/core_ext/float.rb +1 -0
  59. data/lib/active_support/core_ext/float/rounding.rb +19 -0
  60. data/lib/active_support/core_ext/hash.rb +8 -0
  61. data/lib/active_support/core_ext/hash/conversions.rb +150 -0
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +16 -0
  63. data/lib/active_support/core_ext/hash/diff.rb +13 -0
  64. data/lib/active_support/core_ext/hash/except.rb +24 -0
  65. data/lib/active_support/core_ext/hash/indifferent_access.rb +14 -0
  66. data/lib/active_support/core_ext/hash/keys.rb +45 -0
  67. data/lib/active_support/core_ext/hash/reverse_merge.rb +28 -0
  68. data/lib/active_support/core_ext/hash/slice.rb +38 -0
  69. data/lib/active_support/core_ext/integer.rb +3 -0
  70. data/lib/active_support/core_ext/integer/inflections.rb +14 -0
  71. data/lib/active_support/core_ext/integer/multiple.rb +6 -0
  72. data/lib/active_support/core_ext/integer/time.rb +39 -0
  73. data/lib/active_support/core_ext/kernel.rb +5 -0
  74. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  75. data/lib/active_support/core_ext/kernel/debugger.rb +16 -0
  76. data/lib/active_support/core_ext/kernel/reporting.rb +62 -0
  77. data/lib/active_support/core_ext/kernel/requires.rb +26 -0
  78. data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
  79. data/lib/active_support/core_ext/load_error.rb +23 -0
  80. data/lib/active_support/core_ext/logger.rb +146 -0
  81. data/lib/active_support/core_ext/module.rb +12 -0
  82. data/lib/active_support/core_ext/module/aliasing.rb +70 -0
  83. data/lib/active_support/core_ext/module/anonymous.rb +24 -0
  84. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +31 -0
  85. data/lib/active_support/core_ext/module/attr_internal.rb +32 -0
  86. data/lib/active_support/core_ext/module/attribute_accessors.rb +66 -0
  87. data/lib/active_support/core_ext/module/delegation.rb +146 -0
  88. data/lib/active_support/core_ext/module/deprecation.rb +9 -0
  89. data/lib/active_support/core_ext/module/introspection.rb +88 -0
  90. data/lib/active_support/core_ext/module/method_names.rb +14 -0
  91. data/lib/active_support/core_ext/module/reachable.rb +10 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +6 -0
  93. data/lib/active_support/core_ext/module/synchronization.rb +42 -0
  94. data/lib/active_support/core_ext/name_error.rb +18 -0
  95. data/lib/active_support/core_ext/numeric.rb +2 -0
  96. data/lib/active_support/core_ext/numeric/bytes.rb +44 -0
  97. data/lib/active_support/core_ext/numeric/time.rb +77 -0
  98. data/lib/active_support/core_ext/object.rb +14 -0
  99. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  100. data/lib/active_support/core_ext/object/blank.rb +76 -0
  101. data/lib/active_support/core_ext/object/conversions.rb +4 -0
  102. data/lib/active_support/core_ext/object/duplicable.rb +65 -0
  103. data/lib/active_support/core_ext/object/extending.rb +11 -0
  104. data/lib/active_support/core_ext/object/instance_variables.rb +67 -0
  105. data/lib/active_support/core_ext/object/misc.rb +2 -0
  106. data/lib/active_support/core_ext/object/returning.rb +42 -0
  107. data/lib/active_support/core_ext/object/to_param.rb +49 -0
  108. data/lib/active_support/core_ext/object/to_query.rb +27 -0
  109. data/lib/active_support/core_ext/object/try.rb +36 -0
  110. data/lib/active_support/core_ext/object/with_options.rb +26 -0
  111. data/lib/active_support/core_ext/proc.rb +14 -0
  112. data/lib/active_support/core_ext/process.rb +1 -0
  113. data/lib/active_support/core_ext/process/daemon.rb +23 -0
  114. data/lib/active_support/core_ext/range.rb +4 -0
  115. data/lib/active_support/core_ext/range/blockless_step.rb +29 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +21 -0
  117. data/lib/active_support/core_ext/range/include_range.rb +21 -0
  118. data/lib/active_support/core_ext/range/overlaps.rb +8 -0
  119. data/lib/active_support/core_ext/regexp.rb +5 -0
  120. data/lib/active_support/core_ext/rexml.rb +46 -0
  121. data/lib/active_support/core_ext/string.rb +12 -0
  122. data/lib/active_support/core_ext/string/access.rb +99 -0
  123. data/lib/active_support/core_ext/string/behavior.rb +7 -0
  124. data/lib/active_support/core_ext/string/conversions.rb +61 -0
  125. data/lib/active_support/core_ext/string/encoding.rb +11 -0
  126. data/lib/active_support/core_ext/string/exclude.rb +6 -0
  127. data/lib/active_support/core_ext/string/filters.rb +49 -0
  128. data/lib/active_support/core_ext/string/inflections.rb +149 -0
  129. data/lib/active_support/core_ext/string/interpolation.rb +2 -0
  130. data/lib/active_support/core_ext/string/multibyte.rb +72 -0
  131. data/lib/active_support/core_ext/string/output_safety.rb +109 -0
  132. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
  133. data/lib/active_support/core_ext/string/xchar.rb +18 -0
  134. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  135. data/lib/active_support/core_ext/time/calculations.rb +282 -0
  136. data/lib/active_support/core_ext/time/conversions.rb +85 -0
  137. data/lib/active_support/core_ext/time/marshal.rb +56 -0
  138. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +10 -0
  139. data/lib/active_support/core_ext/time/zones.rb +78 -0
  140. data/lib/active_support/core_ext/uri.rb +22 -0
  141. data/lib/active_support/dependencies.rb +628 -0
  142. data/lib/active_support/dependencies/autoload.rb +50 -0
  143. data/lib/active_support/deprecation.rb +18 -0
  144. data/lib/active_support/deprecation/behaviors.rb +38 -0
  145. data/lib/active_support/deprecation/method_wrappers.rb +29 -0
  146. data/lib/active_support/deprecation/proxy_wrappers.rb +74 -0
  147. data/lib/active_support/deprecation/reporting.rb +56 -0
  148. data/lib/active_support/duration.rb +105 -0
  149. data/lib/active_support/gzip.rb +25 -0
  150. data/lib/active_support/hash_with_indifferent_access.rb +145 -0
  151. data/lib/active_support/i18n.rb +8 -0
  152. data/lib/active_support/inflections.rb +56 -0
  153. data/lib/active_support/inflector.rb +7 -0
  154. data/lib/active_support/inflector/inflections.rb +211 -0
  155. data/lib/active_support/inflector/methods.rb +141 -0
  156. data/lib/active_support/inflector/transliterate.rb +97 -0
  157. data/lib/active_support/json.rb +2 -0
  158. data/lib/active_support/json/backends/jsongem.rb +43 -0
  159. data/lib/active_support/json/backends/yajl.rb +40 -0
  160. data/lib/active_support/json/backends/yaml.rb +90 -0
  161. data/lib/active_support/json/decoding.rb +51 -0
  162. data/lib/active_support/json/encoding.rb +254 -0
  163. data/lib/active_support/json/variable.rb +11 -0
  164. data/lib/active_support/lazy_load_hooks.rb +27 -0
  165. data/lib/active_support/locale/en.yml +36 -0
  166. data/lib/active_support/memoizable.rb +103 -0
  167. data/lib/active_support/message_encryptor.rb +71 -0
  168. data/lib/active_support/message_verifier.rb +62 -0
  169. data/lib/active_support/multibyte.rb +44 -0
  170. data/lib/active_support/multibyte/chars.rb +480 -0
  171. data/lib/active_support/multibyte/exceptions.rb +8 -0
  172. data/lib/active_support/multibyte/unicode.rb +393 -0
  173. data/lib/active_support/multibyte/utils.rb +60 -0
  174. data/lib/active_support/notifications.rb +81 -0
  175. data/lib/active_support/notifications/fanout.rb +93 -0
  176. data/lib/active_support/notifications/instrumenter.rb +56 -0
  177. data/lib/active_support/option_merger.rb +25 -0
  178. data/lib/active_support/ordered_hash.rb +158 -0
  179. data/lib/active_support/ordered_options.rb +27 -0
  180. data/lib/active_support/railtie.rb +100 -0
  181. data/lib/active_support/rescuable.rb +114 -0
  182. data/lib/active_support/ruby/shim.rb +22 -0
  183. data/lib/active_support/secure_random.rb +199 -0
  184. data/lib/active_support/string_inquirer.rb +21 -0
  185. data/lib/active_support/test_case.rb +42 -0
  186. data/lib/active_support/testing/assertions.rb +82 -0
  187. data/lib/active_support/testing/declarative.rb +40 -0
  188. data/lib/active_support/testing/default.rb +9 -0
  189. data/lib/active_support/testing/deprecation.rb +55 -0
  190. data/lib/active_support/testing/isolation.rb +154 -0
  191. data/lib/active_support/testing/pending.rb +48 -0
  192. data/lib/active_support/testing/performance.rb +455 -0
  193. data/lib/active_support/testing/setup_and_teardown.rb +111 -0
  194. data/lib/active_support/time.rb +34 -0
  195. data/lib/active_support/time/autoload.rb +5 -0
  196. data/lib/active_support/time_with_zone.rb +341 -0
  197. data/lib/active_support/values/time_zone.rb +377 -0
  198. data/lib/active_support/values/unicode_tables.dat +0 -0
  199. data/lib/active_support/version.rb +10 -0
  200. data/lib/active_support/whiny_nil.rb +60 -0
  201. data/lib/active_support/xml_mini.rb +158 -0
  202. data/lib/active_support/xml_mini/jdom.rb +168 -0
  203. data/lib/active_support/xml_mini/libxml.rb +80 -0
  204. data/lib/active_support/xml_mini/libxmlsax.rb +85 -0
  205. data/lib/active_support/xml_mini/nokogiri.rb +78 -0
  206. data/lib/active_support/xml_mini/nokogirisax.rb +83 -0
  207. data/lib/active_support/xml_mini/rexml.rb +129 -0
  208. data/lib/csd.rb +82 -2
  209. data/lib/csd/application.rb +2 -0
  210. data/lib/csd/application/default.rb +51 -0
  211. data/lib/csd/application/default/base.rb +15 -0
  212. data/lib/csd/application/minisip.rb +25 -0
  213. data/lib/csd/application/minisip/about.yml +14 -0
  214. data/lib/csd/application/minisip/base.rb +161 -0
  215. data/lib/csd/application/minisip/error.rb +11 -0
  216. data/lib/csd/application/minisip/options/common.rb +0 -0
  217. data/lib/csd/application/minisip/options/compile.rb +59 -0
  218. data/lib/csd/{applications → application}/minisip/unix/base.rb +10 -11
  219. data/lib/csd/application/opensips/about.yml +2 -0
  220. data/lib/csd/applications.rb +55 -0
  221. data/lib/csd/commands.rb +88 -65
  222. data/lib/csd/error.rb +31 -0
  223. data/lib/csd/extensions.rb +1 -0
  224. data/lib/{extensions → csd/extensions}/core/array.rb +2 -2
  225. data/lib/csd/extensions/core/dir.rb +46 -0
  226. data/lib/{extensions → csd/extensions}/core/file.rb +2 -2
  227. data/lib/{extensions → csd/extensions}/core/object.rb +2 -2
  228. data/lib/csd/extensions/core/option_parser.rb +33 -0
  229. data/lib/{extensions → csd/extensions}/core/pathname.rb +12 -3
  230. data/lib/{extensions → csd/extensions}/core/string.rb +2 -2
  231. data/lib/{extensions → csd/extensions}/gem/platform.rb +6 -2
  232. data/lib/csd/global_open_struct.rb +18 -0
  233. data/lib/csd/options.rb +124 -95
  234. data/lib/csd/path.rb +31 -0
  235. data/lib/csd/ui.rb +1 -0
  236. data/lib/csd/ui/cli.rb +7 -0
  237. data/lib/csd/ui/ui.rb +46 -0
  238. data/lib/csd/version.rb +9 -0
  239. data/lib/term/ansicolor.rb +102 -0
  240. data/lib/term/ansicolor/.keep +0 -0
  241. data/lib/term/ansicolor/version.rb +10 -0
  242. data/test/functional/test_applications.rb +86 -0
  243. data/test/functional/test_commands.rb +42 -29
  244. data/test/functional/test_options.rb +98 -0
  245. data/test/helper.rb +14 -0
  246. data/test/unit/test_dir.rb +38 -0
  247. data/test/unit/test_pathname.rb +32 -0
  248. metadata +253 -40
  249. data/LICENSE +0 -20
  250. data/bin/csd +0 -8
  251. data/lib/csd/applications/base.rb +0 -33
  252. data/lib/csd/applications/minisip/base.rb +0 -125
  253. data/lib/csd/applications/minisip/init.rb +0 -20
  254. data/lib/csd/init.rb +0 -69
  255. data/lib/csd/path_container.rb +0 -15
  256. data/publish +0 -29
@@ -0,0 +1,22 @@
1
+ class Array
2
+ # Wraps the object in an Array unless it's an Array. Converts the
3
+ # object to an Array using #to_ary if it implements that.
4
+ #
5
+ # It differs with Array() in that it does not call +to_a+ on
6
+ # the argument:
7
+ #
8
+ # Array(:foo => :bar) # => [[:foo, :bar]]
9
+ # Array.wrap(:foo => :bar) # => [{:foo => :bar}]
10
+ #
11
+ # Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
12
+ # Array.wrap("foo\nbar") # => ["foo\nbar"]
13
+ def self.wrap(object)
14
+ if object.nil?
15
+ []
16
+ elsif object.respond_to?(:to_ary)
17
+ object.to_ary
18
+ else
19
+ [object]
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,7 @@
1
+ require 'benchmark'
2
+
3
+ class << Benchmark
4
+ def ms
5
+ 1000 * realtime { yield }
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ require 'active_support/core_ext/big_decimal/conversions'
@@ -0,0 +1,27 @@
1
+ require 'bigdecimal'
2
+ require 'yaml'
3
+
4
+ class BigDecimal
5
+ YAML_TAG = 'tag:yaml.org,2002:float'
6
+ YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
7
+
8
+ yaml_as YAML_TAG
9
+
10
+ # This emits the number without any scientific notation.
11
+ # This is better than self.to_f.to_s since it doesn't lose precision.
12
+ #
13
+ # Note that reconstituting YAML floats to native floats may lose precision.
14
+ def to_yaml(opts = {})
15
+ YAML.quick_emit(nil, opts) do |out|
16
+ string = to_s
17
+ out.scalar(YAML_TAG, YAML_MAPPING[string] || string, :plain)
18
+ end
19
+ end
20
+
21
+ DEFAULT_STRING_FORMAT = 'F'
22
+ def to_formatted_s(format = DEFAULT_STRING_FORMAT)
23
+ _original_to_s(format)
24
+ end
25
+ alias_method :_original_to_s, :to_s
26
+ alias_method :to_s, :to_formatted_s
27
+ end
@@ -0,0 +1 @@
1
+ require 'active_support/core_ext/cgi/escape_skipping_slashes'
@@ -0,0 +1,19 @@
1
+ require 'cgi'
2
+
3
+ class CGI #:nodoc:
4
+ if RUBY_VERSION >= '1.9'
5
+ def self.escape_skipping_slashes(str)
6
+ str = str.join('/') if str.respond_to? :join
7
+ str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
8
+ "%#{$1.unpack('H2' * $1.bytesize).join('%').upcase}"
9
+ end.tr(' ', '+')
10
+ end
11
+ else
12
+ def self.escape_skipping_slashes(str)
13
+ str = str.join('/') if str.respond_to? :join
14
+ str.gsub(/([^ \/a-zA-Z0-9_.-])/n) do
15
+ "%#{$1.unpack('H2').first.upcase}"
16
+ end.tr(' ', '+')
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ require 'active_support/core_ext/class/attribute_accessors'
2
+ require 'active_support/core_ext/class/inheritable_attributes'
3
+ require 'active_support/core_ext/class/delegating_attributes'
4
+ require 'active_support/core_ext/class/subclasses'
@@ -0,0 +1,67 @@
1
+ require 'active_support/core_ext/kernel/singleton_class'
2
+ require 'active_support/core_ext/module/remove_method'
3
+
4
+ class Class
5
+ # Declare a class-level attribute whose value is inheritable and
6
+ # overwritable by subclasses:
7
+ #
8
+ # class Base
9
+ # class_attribute :setting
10
+ # end
11
+ #
12
+ # class Subclass < Base
13
+ # end
14
+ #
15
+ # Base.setting = true
16
+ # Subclass.setting # => true
17
+ # Subclass.setting = false
18
+ # Subclass.setting # => false
19
+ # Base.setting # => true
20
+ #
21
+ # This matches normal Ruby method inheritance: think of writing an attribute
22
+ # on a subclass as overriding the reader method.
23
+ #
24
+ # For convenience, a query method is defined as well:
25
+ #
26
+ # Subclass.setting? # => false
27
+ #
28
+ # Instances may overwrite the class value in the same way:
29
+ #
30
+ # Base.setting = true
31
+ # object = Base.new
32
+ # object.setting # => true
33
+ # object.setting = false
34
+ # object.setting # => false
35
+ # Base.setting # => true
36
+ #
37
+ # To opt out of the instance writer method, pass :instance_writer => false.
38
+ #
39
+ # object.setting = false # => NoMethodError
40
+ def class_attribute(*attrs)
41
+ instance_writer = !attrs.last.is_a?(Hash) || attrs.pop[:instance_writer]
42
+
43
+ attrs.each do |name|
44
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
45
+ def self.#{name}() nil end
46
+ def self.#{name}?() !!#{name} end
47
+
48
+ def self.#{name}=(val)
49
+ singleton_class.class_eval do
50
+ remove_possible_method(:#{name})
51
+ define_method(:#{name}) { val }
52
+ end
53
+ end
54
+
55
+ def #{name}
56
+ defined?(@#{name}) ? @#{name} : singleton_class.#{name}
57
+ end
58
+
59
+ def #{name}?
60
+ !!#{name}
61
+ end
62
+ RUBY
63
+
64
+ attr_writer name if instance_writer
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,63 @@
1
+ require 'active_support/core_ext/array/extract_options'
2
+
3
+ # Extends the class object with class and instance accessors for class attributes,
4
+ # just like the native attr* accessors for instance attributes.
5
+ #
6
+ # class Person
7
+ # cattr_accessor :hair_colors
8
+ # end
9
+ #
10
+ # Person.hair_colors = [:brown, :black, :blonde, :red]
11
+ class Class
12
+ def cattr_reader(*syms)
13
+ options = syms.extract_options!
14
+ syms.each do |sym|
15
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
16
+ unless defined? @@#{sym}
17
+ @@#{sym} = nil
18
+ end
19
+
20
+ def self.#{sym}
21
+ @@#{sym}
22
+ end
23
+ EOS
24
+
25
+ unless options[:instance_reader] == false
26
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
27
+ def #{sym}
28
+ @@#{sym}
29
+ end
30
+ EOS
31
+ end
32
+ end
33
+ end
34
+
35
+ def cattr_writer(*syms)
36
+ options = syms.extract_options!
37
+ syms.each do |sym|
38
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
39
+ unless defined? @@#{sym}
40
+ @@#{sym} = nil
41
+ end
42
+
43
+ def self.#{sym}=(obj)
44
+ @@#{sym} = obj
45
+ end
46
+ EOS
47
+
48
+ unless options[:instance_writer] == false
49
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
50
+ def #{sym}=(obj)
51
+ @@#{sym} = obj
52
+ end
53
+ EOS
54
+ end
55
+ self.send("#{sym}=", yield) if block_given?
56
+ end
57
+ end
58
+
59
+ def cattr_accessor(*syms, &blk)
60
+ cattr_reader(*syms)
61
+ cattr_writer(*syms, &blk)
62
+ end
63
+ end
@@ -0,0 +1,44 @@
1
+ require 'active_support/core_ext/object/blank'
2
+ require 'active_support/core_ext/array/extract_options'
3
+ require 'active_support/core_ext/kernel/singleton_class'
4
+ require 'active_support/core_ext/module/remove_method'
5
+
6
+ class Class
7
+ def superclass_delegating_accessor(name, options = {})
8
+ # Create private _name and _name= methods that can still be used if the public
9
+ # methods are overridden. This allows
10
+ _superclass_delegating_accessor("_#{name}")
11
+
12
+ # Generate the public methods name, name=, and name?
13
+ # These methods dispatch to the private _name, and _name= methods, making them
14
+ # overridable
15
+ singleton_class.send(:define_method, name) { send("_#{name}") }
16
+ singleton_class.send(:define_method, "#{name}?") { !!send("_#{name}") }
17
+ singleton_class.send(:define_method, "#{name}=") { |value| send("_#{name}=", value) }
18
+
19
+ # If an instance_reader is needed, generate methods for name and name= on the
20
+ # class itself, so instances will be able to see them
21
+ define_method(name) { send("_#{name}") } if options[:instance_reader] != false
22
+ define_method("#{name}?") { !!send("#{name}") } if options[:instance_reader] != false
23
+ end
24
+
25
+ private
26
+
27
+ # Take the object being set and store it in a method. This gives us automatic
28
+ # inheritance behavior, without having to store the object in an instance
29
+ # variable and look up the superclass chain manually.
30
+ def _stash_object_in_method(object, method, instance_reader = true)
31
+ singleton_class.remove_possible_method(method)
32
+ singleton_class.send(:define_method, method) { object }
33
+ remove_possible_method(method)
34
+ define_method(method) { object } if instance_reader
35
+ end
36
+
37
+ def _superclass_delegating_accessor(name, options = {})
38
+ singleton_class.send(:define_method, "#{name}=") do |value|
39
+ _stash_object_in_method(value, name, options[:instance_reader] != false)
40
+ end
41
+ send("#{name}=", nil)
42
+ end
43
+
44
+ end
@@ -0,0 +1,232 @@
1
+ require 'active_support/core_ext/object/duplicable'
2
+ require 'active_support/core_ext/array/extract_options'
3
+
4
+ # Retain for backward compatibility. Methods are now included in Class.
5
+ module ClassInheritableAttributes # :nodoc:
6
+ end
7
+
8
+ # Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
9
+ # their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
10
+ # to, for example, an array without those additions being shared with either their parent, siblings, or
11
+ # children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
12
+ #
13
+ # The copies of inheritable parent attributes are added to subclasses when they are created, via the
14
+ # +inherited+ hook.
15
+ class Class # :nodoc:
16
+ def class_inheritable_reader(*syms)
17
+ options = syms.extract_options!
18
+ syms.each do |sym|
19
+ next if sym.is_a?(Hash)
20
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
21
+ def self.#{sym} # def self.after_add
22
+ read_inheritable_attribute(:#{sym}) # read_inheritable_attribute(:after_add)
23
+ end # end
24
+ #
25
+ #{" #
26
+ def #{sym} # def after_add
27
+ self.class.#{sym} # self.class.after_add
28
+ end # end
29
+ " unless options[:instance_reader] == false } # # the reader above is generated unless options[:instance_reader] == false
30
+ EOS
31
+ end
32
+ end
33
+
34
+ def class_inheritable_writer(*syms)
35
+ options = syms.extract_options!
36
+ syms.each do |sym|
37
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
38
+ def self.#{sym}=(obj) # def self.color=(obj)
39
+ write_inheritable_attribute(:#{sym}, obj) # write_inheritable_attribute(:color, obj)
40
+ end # end
41
+ #
42
+ #{" #
43
+ def #{sym}=(obj) # def color=(obj)
44
+ self.class.#{sym} = obj # self.class.color = obj
45
+ end # end
46
+ " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
47
+ EOS
48
+ end
49
+ end
50
+
51
+ def class_inheritable_array_writer(*syms)
52
+ options = syms.extract_options!
53
+ syms.each do |sym|
54
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
55
+ def self.#{sym}=(obj) # def self.levels=(obj)
56
+ write_inheritable_array(:#{sym}, obj) # write_inheritable_array(:levels, obj)
57
+ end # end
58
+ #
59
+ #{" #
60
+ def #{sym}=(obj) # def levels=(obj)
61
+ self.class.#{sym} = obj # self.class.levels = obj
62
+ end # end
63
+ " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
64
+ EOS
65
+ end
66
+ end
67
+
68
+ def class_inheritable_hash_writer(*syms)
69
+ options = syms.extract_options!
70
+ syms.each do |sym|
71
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
72
+ def self.#{sym}=(obj) # def self.nicknames=(obj)
73
+ write_inheritable_hash(:#{sym}, obj) # write_inheritable_hash(:nicknames, obj)
74
+ end # end
75
+ #
76
+ #{" #
77
+ def #{sym}=(obj) # def nicknames=(obj)
78
+ self.class.#{sym} = obj # self.class.nicknames = obj
79
+ end # end
80
+ " unless options[:instance_writer] == false } # # the writer above is generated unless options[:instance_writer] == false
81
+ EOS
82
+ end
83
+ end
84
+
85
+ def class_inheritable_accessor(*syms)
86
+ class_inheritable_reader(*syms)
87
+ class_inheritable_writer(*syms)
88
+ end
89
+
90
+ def class_inheritable_array(*syms)
91
+ class_inheritable_reader(*syms)
92
+ class_inheritable_array_writer(*syms)
93
+ end
94
+
95
+ def class_inheritable_hash(*syms)
96
+ class_inheritable_reader(*syms)
97
+ class_inheritable_hash_writer(*syms)
98
+ end
99
+
100
+ def inheritable_attributes
101
+ @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
102
+ end
103
+
104
+ def write_inheritable_attribute(key, value)
105
+ if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
106
+ @inheritable_attributes = {}
107
+ end
108
+ inheritable_attributes[key] = value
109
+ end
110
+
111
+ def write_inheritable_array(key, elements)
112
+ write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
113
+ write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
114
+ end
115
+
116
+ def write_inheritable_hash(key, hash)
117
+ write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
118
+ write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
119
+ end
120
+
121
+ def read_inheritable_attribute(key)
122
+ inheritable_attributes[key]
123
+ end
124
+
125
+ def reset_inheritable_attributes
126
+ @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
127
+ end
128
+
129
+ private
130
+ # Prevent this constant from being created multiple times
131
+ EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
132
+
133
+ def inherited_with_inheritable_attributes(child)
134
+ inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
135
+
136
+ if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
137
+ new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
138
+ else
139
+ new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
140
+ memo.update(key => value.duplicable? ? value.dup : value)
141
+ end
142
+ end
143
+
144
+ child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
145
+ end
146
+
147
+ alias inherited_without_inheritable_attributes inherited
148
+ alias inherited inherited_with_inheritable_attributes
149
+ end
150
+
151
+ class Class
152
+ # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
153
+ # each subclass has a copy of parent's attribute.
154
+ #
155
+ # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
156
+ # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
157
+ #
158
+ # @api public
159
+ #
160
+ # @todo Do we want to block instance_reader via :instance_reader => false
161
+ # @todo It would be preferable that we do something with a Hash passed in
162
+ # (error out or do the same as other methods above) instead of silently
163
+ # moving on). In particular, this makes the return value of this function
164
+ # less useful.
165
+ def extlib_inheritable_reader(*ivars, &block)
166
+ options = ivars.extract_options!
167
+
168
+ ivars.each do |ivar|
169
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
170
+ def self.#{ivar}
171
+ return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
172
+ ivar = superclass.#{ivar}
173
+ return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
174
+ @#{ivar} = ivar.duplicable? ? ivar.dup : ivar
175
+ end
176
+ RUBY
177
+ unless options[:instance_reader] == false
178
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
179
+ def #{ivar}
180
+ self.class.#{ivar}
181
+ end
182
+ RUBY
183
+ end
184
+ instance_variable_set(:"@#{ivar}", yield) if block_given?
185
+ end
186
+ end
187
+
188
+ # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
189
+ # each subclass has a copy of parent's attribute.
190
+ #
191
+ # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
192
+ # define inheritable writer for.
193
+ # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
194
+ # @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
195
+ #
196
+ # @api public
197
+ #
198
+ # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
199
+ # class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
200
+ def extlib_inheritable_writer(*ivars)
201
+ options = ivars.extract_options!
202
+
203
+ ivars.each do |ivar|
204
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
205
+ def self.#{ivar}=(obj)
206
+ @#{ivar} = obj
207
+ end
208
+ RUBY
209
+ unless options[:instance_writer] == false
210
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
211
+ def #{ivar}=(obj) self.class.#{ivar} = obj end
212
+ RUBY
213
+ end
214
+
215
+ self.send("#{ivar}=", yield) if block_given?
216
+ end
217
+ end
218
+
219
+ # Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
220
+ # each subclass has a copy of parent's attribute.
221
+ #
222
+ # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
223
+ # define inheritable accessor for.
224
+ # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
225
+ # @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
226
+ #
227
+ # @api public
228
+ def extlib_inheritable_accessor(*syms, &block)
229
+ extlib_inheritable_reader(*syms)
230
+ extlib_inheritable_writer(*syms, &block)
231
+ end
232
+ end