monetra-ruby 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/Rakefile +35 -0
  2. data/lib/monetra.rb +239 -0
  3. data/lib/monetra/active_support.rb +42 -0
  4. data/lib/monetra/active_support/binding_of_caller.rb +84 -0
  5. data/lib/monetra/active_support/breakpoint.rb +523 -0
  6. data/lib/monetra/active_support/caching_tools.rb +62 -0
  7. data/lib/monetra/active_support/clean_logger.rb +38 -0
  8. data/lib/monetra/active_support/core_ext.rb +1 -0
  9. data/lib/monetra/active_support/core_ext/array.rb +7 -0
  10. data/lib/monetra/active_support/core_ext/array/conversions.rb +72 -0
  11. data/lib/monetra/active_support/core_ext/array/grouping.rb +46 -0
  12. data/lib/monetra/active_support/core_ext/bigdecimal.rb +3 -0
  13. data/lib/monetra/active_support/core_ext/bigdecimal/formatting.rb +7 -0
  14. data/lib/monetra/active_support/core_ext/blank.rb +50 -0
  15. data/lib/monetra/active_support/core_ext/cgi.rb +5 -0
  16. data/lib/monetra/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -0
  17. data/lib/monetra/active_support/core_ext/class.rb +3 -0
  18. data/lib/monetra/active_support/core_ext/class/attribute_accessors.rb +44 -0
  19. data/lib/monetra/active_support/core_ext/class/inheritable_attributes.rb +115 -0
  20. data/lib/monetra/active_support/core_ext/class/removal.rb +24 -0
  21. data/lib/monetra/active_support/core_ext/date.rb +6 -0
  22. data/lib/monetra/active_support/core_ext/date/conversions.rb +39 -0
  23. data/lib/monetra/active_support/core_ext/enumerable.rb +62 -0
  24. data/lib/monetra/active_support/core_ext/exception.rb +33 -0
  25. data/lib/monetra/active_support/core_ext/hash.rb +13 -0
  26. data/lib/monetra/active_support/core_ext/hash/conversions.rb +148 -0
  27. data/lib/monetra/active_support/core_ext/hash/diff.rb +11 -0
  28. data/lib/monetra/active_support/core_ext/hash/indifferent_access.rb +88 -0
  29. data/lib/monetra/active_support/core_ext/hash/keys.rb +53 -0
  30. data/lib/monetra/active_support/core_ext/hash/reverse_merge.rb +25 -0
  31. data/lib/monetra/active_support/core_ext/integer.rb +7 -0
  32. data/lib/monetra/active_support/core_ext/integer/even_odd.rb +24 -0
  33. data/lib/monetra/active_support/core_ext/integer/inflections.rb +15 -0
  34. data/lib/monetra/active_support/core_ext/kernel.rb +4 -0
  35. data/lib/monetra/active_support/core_ext/kernel/agnostics.rb +11 -0
  36. data/lib/monetra/active_support/core_ext/kernel/daemonizing.rb +15 -0
  37. data/lib/monetra/active_support/core_ext/kernel/reporting.rb +51 -0
  38. data/lib/monetra/active_support/core_ext/kernel/requires.rb +24 -0
  39. data/lib/monetra/active_support/core_ext/load_error.rb +38 -0
  40. data/lib/monetra/active_support/core_ext/logger.rb +16 -0
  41. data/lib/monetra/active_support/core_ext/module.rb +7 -0
  42. data/lib/monetra/active_support/core_ext/module/aliasing.rb +57 -0
  43. data/lib/monetra/active_support/core_ext/module/attr_internal.rb +31 -0
  44. data/lib/monetra/active_support/core_ext/module/attribute_accessors.rb +44 -0
  45. data/lib/monetra/active_support/core_ext/module/delegation.rb +41 -0
  46. data/lib/monetra/active_support/core_ext/module/inclusion.rb +11 -0
  47. data/lib/monetra/active_support/core_ext/module/introspection.rb +21 -0
  48. data/lib/monetra/active_support/core_ext/module/loading.rb +13 -0
  49. data/lib/monetra/active_support/core_ext/name_error.rb +20 -0
  50. data/lib/monetra/active_support/core_ext/numeric.rb +7 -0
  51. data/lib/monetra/active_support/core_ext/numeric/bytes.rb +44 -0
  52. data/lib/monetra/active_support/core_ext/numeric/time.rb +72 -0
  53. data/lib/monetra/active_support/core_ext/object.rb +2 -0
  54. data/lib/monetra/active_support/core_ext/object/extending.rb +47 -0
  55. data/lib/monetra/active_support/core_ext/object/misc.rb +34 -0
  56. data/lib/monetra/active_support/core_ext/pathname.rb +7 -0
  57. data/lib/monetra/active_support/core_ext/pathname/clean_within.rb +14 -0
  58. data/lib/monetra/active_support/core_ext/proc.rb +12 -0
  59. data/lib/monetra/active_support/core_ext/range.rb +5 -0
  60. data/lib/monetra/active_support/core_ext/range/conversions.rb +21 -0
  61. data/lib/monetra/active_support/core_ext/string.rb +13 -0
  62. data/lib/monetra/active_support/core_ext/string/access.rb +58 -0
  63. data/lib/monetra/active_support/core_ext/string/conversions.rb +19 -0
  64. data/lib/monetra/active_support/core_ext/string/inflections.rb +153 -0
  65. data/lib/monetra/active_support/core_ext/string/iterators.rb +17 -0
  66. data/lib/monetra/active_support/core_ext/string/starts_ends_with.rb +20 -0
  67. data/lib/monetra/active_support/core_ext/symbol.rb +12 -0
  68. data/lib/monetra/active_support/core_ext/time.rb +7 -0
  69. data/lib/monetra/active_support/core_ext/time/calculations.rb +188 -0
  70. data/lib/monetra/active_support/core_ext/time/conversions.rb +36 -0
  71. data/lib/monetra/active_support/dependencies.rb +187 -0
  72. data/lib/monetra/active_support/deprecation.rb +106 -0
  73. data/lib/monetra/active_support/inflections.rb +53 -0
  74. data/lib/monetra/active_support/inflector.rb +179 -0
  75. data/lib/monetra/active_support/json.rb +37 -0
  76. data/lib/monetra/active_support/json/encoders.rb +25 -0
  77. data/lib/monetra/active_support/json/encoders/core.rb +65 -0
  78. data/lib/monetra/active_support/option_merger.rb +25 -0
  79. data/lib/monetra/active_support/ordered_options.rb +50 -0
  80. data/lib/monetra/active_support/reloadable.rb +30 -0
  81. data/lib/monetra/active_support/values/time_zone.rb +180 -0
  82. data/lib/monetra/active_support/vendor/builder.rb +13 -0
  83. data/lib/monetra/active_support/vendor/builder/blankslate.rb +63 -0
  84. data/lib/monetra/active_support/vendor/builder/xchar.rb +112 -0
  85. data/lib/monetra/active_support/vendor/builder/xmlbase.rb +145 -0
  86. data/lib/monetra/active_support/vendor/builder/xmlevents.rb +63 -0
  87. data/lib/monetra/active_support/vendor/builder/xmlmarkup.rb +328 -0
  88. data/lib/monetra/active_support/vendor/flexmock.rb +84 -0
  89. data/lib/monetra/active_support/vendor/xml_simple.rb +1019 -0
  90. data/lib/monetra/active_support/version.rb +9 -0
  91. data/lib/monetra/active_support/whiny_nil.rb +38 -0
  92. data/test/test.rb +21 -0
  93. metadata +167 -0
@@ -0,0 +1,106 @@
1
+ module ActiveSupport
2
+ module Deprecation
3
+ # Choose the default warn behavior according to RAILS_ENV.
4
+ # Ignore deprecation warnings in production.
5
+ DEFAULT_BEHAVIORS = {
6
+ 'test' => Proc.new { |message| $stderr.puts message },
7
+ 'development' => Proc.new { |message| RAILS_DEFAULT_LOGGER.warn message },
8
+ }
9
+
10
+ class << self
11
+ def warn(message = nil, callstack = caller)
12
+ behavior.call(deprecation_message(callstack, message)) if behavior
13
+ end
14
+
15
+ def default_behavior
16
+ DEFAULT_BEHAVIORS[RAILS_ENV.to_s] if defined?(RAILS_ENV)
17
+ end
18
+
19
+ private
20
+ def deprecation_message(callstack, message = nil)
21
+ file, line, method = extract_callstack(callstack)
22
+ message ||= "WARNING: #{method} is deprecated and will be removed from the next Rails release"
23
+ "#{message} (#{method} at #{file}:#{line})"
24
+ end
25
+
26
+ def extract_callstack(callstack)
27
+ callstack.first.match(/^(.+?):(\d+)(?::in `(.*?)')?/).captures
28
+ end
29
+ end
30
+
31
+ # Behavior is a block that takes a message argument.
32
+ mattr_accessor :behavior
33
+ self.behavior = default_behavior
34
+
35
+ module ClassMethods
36
+ # Declare that a method has been deprecated.
37
+ def deprecate(*method_names)
38
+ method_names.each do |method_name|
39
+ class_eval(<<-EOS, __FILE__, __LINE__)
40
+ def #{method_name}_with_deprecation(*args, &block)
41
+ ::ActiveSupport::Deprecation.warn
42
+ #{method_name}_without_deprecation(*args, &block)
43
+ end
44
+ EOS
45
+ alias_method_chain(method_name, :deprecation)
46
+ end
47
+ end
48
+ end
49
+
50
+ module Assertions
51
+ def assert_deprecated(match = nil, &block)
52
+ last = with_last_message_tracking_deprecation_behavior(&block)
53
+ assert last, "Expected a deprecation warning within the block but received none"
54
+ match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
55
+ assert_match match, last, "Deprecation warning didn't match #{match}: #{last}"
56
+ end
57
+
58
+ def assert_not_deprecated(&block)
59
+ last = with_last_message_tracking_deprecation_behavior(&block)
60
+ assert_nil last, "Expected no deprecation warning within the block but received one: #{last}"
61
+ end
62
+
63
+ private
64
+ def with_last_message_tracking_deprecation_behavior
65
+ old_behavior = ActiveSupport::Deprecation.behavior
66
+ last_message = nil
67
+ ActiveSupport::Deprecation.behavior = Proc.new { |message| last_message = message; old_behavior.call(message) if old_behavior }
68
+ yield
69
+ last_message
70
+ ensure
71
+ ActiveSupport::Deprecation.behavior = old_behavior
72
+ end
73
+ end
74
+
75
+ # Stand-in for @request, @attributes, etc.
76
+ class DeprecatedInstanceVariableProxy
77
+ instance_methods.each { |m| undef_method m unless m =~ /^__/ }
78
+
79
+ def initialize(instance, method, var = "@#{method}")
80
+ @instance, @method, @var = instance, method, var
81
+ end
82
+
83
+ private
84
+ def warn(callstack, called, args)
85
+ ActiveSupport::Deprecation.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack)
86
+ end
87
+
88
+ def method_missing(called, *args, &block)
89
+ warn caller, called, args
90
+ @instance.__send__(@method).__send__(called, *args, &block)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ class Class
97
+ include ActiveSupport::Deprecation::ClassMethods
98
+ end
99
+
100
+ module Test
101
+ module Unit
102
+ class TestCase
103
+ include ActiveSupport::Deprecation::Assertions
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,53 @@
1
+ Inflector.inflections do |inflect|
2
+ inflect.plural(/$/, 's')
3
+ inflect.plural(/s$/i, 's')
4
+ inflect.plural(/(ax|test)is$/i, '\1es')
5
+ inflect.plural(/(octop|vir)us$/i, '\1i')
6
+ inflect.plural(/(alias|status)$/i, '\1es')
7
+ inflect.plural(/(bu)s$/i, '\1ses')
8
+ inflect.plural(/(buffal|tomat)o$/i, '\1oes')
9
+ inflect.plural(/([ti])um$/i, '\1a')
10
+ inflect.plural(/sis$/i, 'ses')
11
+ inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
12
+ inflect.plural(/(hive)$/i, '\1s')
13
+ inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
14
+ inflect.plural(/([^aeiouy]|qu)ies$/i, '\1y')
15
+ inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
16
+ inflect.plural(/(matr|vert|ind)ix|ex$/i, '\1ices')
17
+ inflect.plural(/([m|l])ouse$/i, '\1ice')
18
+ inflect.plural(/^(ox)$/i, '\1en')
19
+ inflect.plural(/(quiz)$/i, '\1zes')
20
+
21
+ inflect.singular(/s$/i, '')
22
+ inflect.singular(/(n)ews$/i, '\1ews')
23
+ inflect.singular(/([ti])a$/i, '\1um')
24
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
25
+ inflect.singular(/(^analy)ses$/i, '\1sis')
26
+ inflect.singular(/([^f])ves$/i, '\1fe')
27
+ inflect.singular(/(hive)s$/i, '\1')
28
+ inflect.singular(/(tive)s$/i, '\1')
29
+ inflect.singular(/([lr])ves$/i, '\1f')
30
+ inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y')
31
+ inflect.singular(/(s)eries$/i, '\1eries')
32
+ inflect.singular(/(m)ovies$/i, '\1ovie')
33
+ inflect.singular(/(x|ch|ss|sh)es$/i, '\1')
34
+ inflect.singular(/([m|l])ice$/i, '\1ouse')
35
+ inflect.singular(/(bus)es$/i, '\1')
36
+ inflect.singular(/(o)es$/i, '\1')
37
+ inflect.singular(/(shoe)s$/i, '\1')
38
+ inflect.singular(/(cris|ax|test)es$/i, '\1is')
39
+ inflect.singular(/(octop|vir)i$/i, '\1us')
40
+ inflect.singular(/(alias|status)es$/i, '\1')
41
+ inflect.singular(/^(ox)en/i, '\1')
42
+ inflect.singular(/(vert|ind)ices$/i, '\1ex')
43
+ inflect.singular(/(matr)ices$/i, '\1ix')
44
+ inflect.singular(/(quiz)zes$/i, '\1')
45
+
46
+ inflect.irregular('person', 'people')
47
+ inflect.irregular('man', 'men')
48
+ inflect.irregular('child', 'children')
49
+ inflect.irregular('sex', 'sexes')
50
+ inflect.irregular('move', 'moves')
51
+
52
+ inflect.uncountable(%w(equipment information rice money species series fish sheep))
53
+ end
@@ -0,0 +1,179 @@
1
+ require 'singleton'
2
+
3
+ # The Inflector transforms words from singular to plural, class names to table names, modularized class names to ones without,
4
+ # and class names to foreign keys. The default inflections for pluralization, singularization, and uncountable words are kept
5
+ # in inflections.rb.
6
+ module Inflector
7
+ # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
8
+ # inflection rules. Examples:
9
+ #
10
+ # Inflector.inflections do |inflect|
11
+ # inflect.plural /^(ox)$/i, '\1\2en'
12
+ # inflect.singular /^(ox)en/i, '\1'
13
+ #
14
+ # inflect.irregular 'octopus', 'octopi'
15
+ #
16
+ # inflect.uncountable "equipment"
17
+ # end
18
+ #
19
+ # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
20
+ # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
21
+ # already have been loaded.
22
+ class Inflections
23
+ include Singleton
24
+
25
+ attr_reader :plurals, :singulars, :uncountables
26
+
27
+ def initialize
28
+ @plurals, @singulars, @uncountables = [], [], []
29
+ end
30
+
31
+ # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
32
+ # The replacement should always be a string that may include references to the matched data from the rule.
33
+ def plural(rule, replacement)
34
+ @plurals.insert(0, [rule, replacement])
35
+ end
36
+
37
+ # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
38
+ # The replacement should always be a string that may include references to the matched data from the rule.
39
+ def singular(rule, replacement)
40
+ @singulars.insert(0, [rule, replacement])
41
+ end
42
+
43
+ # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
44
+ # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
45
+ #
46
+ # Examples:
47
+ # irregular 'octopus', 'octopi'
48
+ # irregular 'person', 'people'
49
+ def irregular(singular, plural)
50
+ plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
51
+ singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
52
+ end
53
+
54
+ # Add uncountable words that shouldn't be attempted inflected.
55
+ #
56
+ # Examples:
57
+ # uncountable "money"
58
+ # uncountable "money", "information"
59
+ # uncountable %w( money information rice )
60
+ def uncountable(*words)
61
+ (@uncountables << words).flatten!
62
+ end
63
+
64
+ # Clears the loaded inflections within a given scope (default is :all). Give the scope as a symbol of the inflection type,
65
+ # the options are: :plurals, :singulars, :uncountables
66
+ #
67
+ # Examples:
68
+ # clear :all
69
+ # clear :plurals
70
+ def clear(scope = :all)
71
+ case scope
72
+ when :all
73
+ @plurals, @singulars, @uncountables = [], [], []
74
+ else
75
+ instance_variable_set "@#{scope}", []
76
+ end
77
+ end
78
+ end
79
+
80
+ extend self
81
+
82
+ def inflections
83
+ if block_given?
84
+ yield Inflections.instance
85
+ else
86
+ Inflections.instance
87
+ end
88
+ end
89
+
90
+ def pluralize(word)
91
+ result = word.to_s.dup
92
+
93
+ if inflections.uncountables.include?(result.downcase)
94
+ result
95
+ else
96
+ inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
97
+ result
98
+ end
99
+ end
100
+
101
+ def singularize(word)
102
+ result = word.to_s.dup
103
+
104
+ if inflections.uncountables.include?(result.downcase)
105
+ result
106
+ else
107
+ inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
108
+ result
109
+ end
110
+ end
111
+
112
+ def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
113
+ if first_letter_in_uppercase
114
+ lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
115
+ else
116
+ lower_case_and_underscored_word.first + camelize(lower_case_and_underscored_word)[1..-1]
117
+ end
118
+ end
119
+
120
+ def titleize(word)
121
+ humanize(underscore(word)).gsub(/\b([a-z])/) { $1.capitalize }
122
+ end
123
+
124
+ def underscore(camel_cased_word)
125
+ camel_cased_word.to_s.gsub(/::/, '/').
126
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
127
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
128
+ tr("-", "_").
129
+ downcase
130
+ end
131
+
132
+ def dasherize(underscored_word)
133
+ underscored_word.gsub(/_/, '-')
134
+ end
135
+
136
+ def humanize(lower_case_and_underscored_word)
137
+ lower_case_and_underscored_word.to_s.gsub(/_id$/, "").gsub(/_/, " ").capitalize
138
+ end
139
+
140
+ def demodulize(class_name_in_module)
141
+ class_name_in_module.to_s.gsub(/^.*::/, '')
142
+ end
143
+
144
+ def tableize(class_name)
145
+ pluralize(underscore(class_name))
146
+ end
147
+
148
+ def classify(table_name)
149
+ # strip out any leading schema name
150
+ camelize(singularize(table_name.to_s.sub(/.*\./, '')))
151
+ end
152
+
153
+ def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
154
+ underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id")
155
+ end
156
+
157
+ def constantize(camel_cased_word)
158
+ raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!" unless
159
+ /^(::)?([A-Z]\w*)(::[A-Z]\w*)*$/ =~ camel_cased_word
160
+
161
+ camel_cased_word = "::#{camel_cased_word}" unless $1
162
+ Object.module_eval(camel_cased_word, __FILE__, __LINE__)
163
+ end
164
+
165
+ def ordinalize(number)
166
+ if (11..13).include?(number.to_i % 100)
167
+ "#{number}th"
168
+ else
169
+ case number.to_i % 10
170
+ when 1: "#{number}st"
171
+ when 2: "#{number}nd"
172
+ when 3: "#{number}rd"
173
+ else "#{number}th"
174
+ end
175
+ end
176
+ end
177
+ end
178
+
179
+ require File.dirname(__FILE__) + '/inflections'
@@ -0,0 +1,37 @@
1
+ require 'active_support/json/encoders'
2
+
3
+ module ActiveSupport
4
+ module JSON #:nodoc:
5
+ class CircularReferenceError < StandardError #:nodoc:
6
+ end
7
+ # returns the literal string as its JSON encoded form. Useful for passing javascript variables into functions.
8
+ #
9
+ # page.call 'Element.show', ActiveSupport::JSON::Variable.new("$$(#items li)")
10
+ class Variable < String #:nodoc:
11
+ def to_json
12
+ self
13
+ end
14
+ end
15
+
16
+ class << self
17
+ REFERENCE_STACK_VARIABLE = :json_reference_stack
18
+
19
+ def encode(value)
20
+ raise_on_circular_reference(value) do
21
+ Encoders[value.class].call(value)
22
+ end
23
+ end
24
+
25
+ protected
26
+ def raise_on_circular_reference(value)
27
+ stack = Thread.current[REFERENCE_STACK_VARIABLE] ||= []
28
+ raise CircularReferenceError, 'object references itself' if
29
+ stack.include? value
30
+ stack << value
31
+ yield
32
+ ensure
33
+ stack.pop
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ module ActiveSupport
2
+ module JSON #:nodoc:
3
+ module Encoders
4
+ mattr_accessor :encoders
5
+ @@encoders = {}
6
+
7
+ class << self
8
+ def define_encoder(klass, &block)
9
+ encoders[klass] = block
10
+ end
11
+
12
+ def [](klass)
13
+ klass.ancestors.each do |k|
14
+ encoder = encoders[k]
15
+ return encoder if encoder
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ Dir[File.dirname(__FILE__) + '/encoders/*.rb'].each do |file|
24
+ require file[0..-4]
25
+ end
@@ -0,0 +1,65 @@
1
+ module ActiveSupport
2
+ module JSON #:nodoc:
3
+ module Encoders #:nodoc:
4
+ define_encoder Object do |object|
5
+ object.instance_values.to_json
6
+ end
7
+
8
+ define_encoder TrueClass do
9
+ 'true'
10
+ end
11
+
12
+ define_encoder FalseClass do
13
+ 'false'
14
+ end
15
+
16
+ define_encoder NilClass do
17
+ 'null'
18
+ end
19
+
20
+ define_encoder String do |string|
21
+ returning value = '"' do
22
+ string.each_char do |char|
23
+ value << case
24
+ when char == "\010": '\b'
25
+ when char == "\f": '\f'
26
+ when char == "\n": '\n'
27
+ when char == "\r": '\r'
28
+ when char == "\t": '\t'
29
+ when char == '"': '\"'
30
+ when char == '\\': '\\\\'
31
+ when char.length > 1: "\\u#{'%04x' % char.unpack('U').first}"
32
+ else; char
33
+ end
34
+ end
35
+ value << '"'
36
+ end
37
+ end
38
+
39
+ define_encoder Numeric do |numeric|
40
+ numeric.to_s
41
+ end
42
+
43
+ define_encoder Symbol do |symbol|
44
+ symbol.to_s.to_json
45
+ end
46
+
47
+ define_encoder Enumerable do |enumerable|
48
+ "[#{enumerable.map { |value| value.to_json } * ', '}]"
49
+ end
50
+
51
+ define_encoder Hash do |hash|
52
+ returning result = '{' do
53
+ result << hash.map do |pair|
54
+ pair.map { |value| value.to_json } * ': '
55
+ end * ', '
56
+ result << '}'
57
+ end
58
+ end
59
+
60
+ define_encoder Regexp do |regexp|
61
+ regexp.inspect
62
+ end
63
+ end
64
+ end
65
+ end