gorillib 0.1.11 → 0.4.0pre

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 (143) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +1 -2
  3. data/.yardopts +9 -0
  4. data/{CHANGELOG.textile → CHANGELOG.md} +35 -9
  5. data/Gemfile +21 -14
  6. data/Guardfile +19 -0
  7. data/{LICENSE.textile → LICENSE.md} +43 -29
  8. data/README.md +47 -52
  9. data/Rakefile +31 -30
  10. data/TODO.md +32 -0
  11. data/VERSION +1 -1
  12. data/examples/builder/ironfan.rb +133 -0
  13. data/examples/model/simple.rb +17 -0
  14. data/gorillib.gemspec +106 -86
  15. data/lib/alt/kernel/call_stack.rb +56 -0
  16. data/lib/gorillib/array/wrap.rb +53 -0
  17. data/lib/gorillib/base.rb +3 -3
  18. data/lib/gorillib/builder/field.rb +5 -0
  19. data/lib/gorillib/builder.rb +260 -0
  20. data/lib/gorillib/collection/has_collection.rb +31 -0
  21. data/lib/gorillib/collection.rb +129 -0
  22. data/lib/gorillib/configurable.rb +28 -0
  23. data/lib/gorillib/datetime/{flat.rb → to_flat.rb} +0 -0
  24. data/lib/gorillib/exception/confidence.rb +17 -0
  25. data/lib/gorillib/exception/raisers.rb +78 -0
  26. data/lib/gorillib/hash/mash.rb +202 -0
  27. data/lib/gorillib/hashlike/slice.rb +53 -19
  28. data/lib/gorillib/hashlike.rb +5 -3
  29. data/lib/gorillib/io/system_helpers.rb +30 -0
  30. data/lib/gorillib/logger/log.rb +18 -0
  31. data/lib/gorillib/metaprogramming/concern.rb +124 -0
  32. data/lib/gorillib/model/active_model_conversion.rb +68 -0
  33. data/lib/gorillib/model/active_model_naming.rb +87 -0
  34. data/lib/gorillib/model/active_model_shim.rb +33 -0
  35. data/lib/gorillib/model/base.rb +341 -0
  36. data/lib/gorillib/model/defaults.rb +71 -0
  37. data/lib/gorillib/model/errors.rb +14 -0
  38. data/lib/gorillib/model/factories.rb +372 -0
  39. data/lib/gorillib/model/field.rb +146 -0
  40. data/lib/gorillib/model/named_schema.rb +53 -0
  41. data/lib/gorillib/{struct/hashlike_iteration.rb → model/overlay.rb} +0 -0
  42. data/lib/gorillib/model/record_schema.rb +9 -0
  43. data/lib/gorillib/model/serialization.rb +23 -0
  44. data/lib/gorillib/model/validate.rb +22 -0
  45. data/lib/gorillib/model.rb +23 -0
  46. data/lib/gorillib/pathname.rb +78 -0
  47. data/lib/gorillib/{serialization.rb → serialization/to_wire.rb} +0 -0
  48. data/lib/gorillib/some.rb +11 -9
  49. data/lib/gorillib/string/constantize.rb +21 -14
  50. data/lib/gorillib/string/inflections.rb +6 -76
  51. data/lib/gorillib/string/inflector.rb +192 -0
  52. data/lib/gorillib/string/simple_inflector.rb +267 -0
  53. data/lib/gorillib/type/extended.rb +52 -0
  54. data/lib/gorillib/utils/capture_output.rb +28 -0
  55. data/lib/gorillib/utils/console.rb +131 -0
  56. data/lib/gorillib/utils/nuke_constants.rb +9 -0
  57. data/lib/gorillib/utils/stub_module.rb +33 -0
  58. data/spec/examples/builder/ironfan_spec.rb +37 -0
  59. data/spec/extlib/hash_spec.rb +64 -0
  60. data/spec/extlib/mash_spec.rb +312 -0
  61. data/spec/{array → gorillib/array}/compact_blank_spec.rb +2 -2
  62. data/spec/{array → gorillib/array}/extract_options_spec.rb +2 -2
  63. data/spec/gorillib/builder_spec.rb +187 -0
  64. data/spec/gorillib/collection_spec.rb +20 -0
  65. data/spec/gorillib/configurable_spec.rb +62 -0
  66. data/spec/{datetime → gorillib/datetime}/parse_spec.rb +3 -3
  67. data/spec/{datetime/flat_spec.rb → gorillib/datetime/to_flat_spec.rb} +4 -4
  68. data/spec/{enumerable → gorillib/enumerable}/sum_spec.rb +5 -5
  69. data/spec/gorillib/exception/raisers_spec.rb +60 -0
  70. data/spec/{hash → gorillib/hash}/compact_spec.rb +2 -2
  71. data/spec/{hash → gorillib/hash}/deep_compact_spec.rb +3 -3
  72. data/spec/{hash → gorillib/hash}/deep_merge_spec.rb +2 -2
  73. data/spec/{hash → gorillib/hash}/keys_spec.rb +2 -2
  74. data/spec/{hash → gorillib/hash}/reverse_merge_spec.rb +2 -2
  75. data/spec/{hash → gorillib/hash}/slice_spec.rb +2 -2
  76. data/spec/{hash → gorillib/hash}/zip_spec.rb +2 -2
  77. data/spec/{hashlike → gorillib/hashlike}/behave_same_as_hash_spec.rb +6 -3
  78. data/spec/{hashlike → gorillib/hashlike}/deep_hash_spec.rb +2 -2
  79. data/spec/{hashlike → gorillib/hashlike}/hashlike_behavior_spec.rb +32 -30
  80. data/spec/{hashlike → gorillib/hashlike}/hashlike_via_accessors_spec.rb +3 -3
  81. data/spec/{hashlike_spec.rb → gorillib/hashlike_spec.rb} +3 -3
  82. data/spec/{logger → gorillib/logger}/log_spec.rb +2 -2
  83. data/spec/{metaprogramming → gorillib/metaprogramming}/aliasing_spec.rb +3 -3
  84. data/spec/{metaprogramming → gorillib/metaprogramming}/class_attribute_spec.rb +3 -3
  85. data/spec/{metaprogramming → gorillib/metaprogramming}/delegation_spec.rb +3 -3
  86. data/spec/{metaprogramming → gorillib/metaprogramming}/singleton_class_spec.rb +3 -3
  87. data/spec/gorillib/model/record/defaults_spec.rb +108 -0
  88. data/spec/gorillib/model/record/factories_spec.rb +321 -0
  89. data/spec/gorillib/model/record/overlay_spec.rb +46 -0
  90. data/spec/gorillib/model/serialization_spec.rb +48 -0
  91. data/spec/gorillib/model_spec.rb +281 -0
  92. data/spec/{numeric → gorillib/numeric}/clamp_spec.rb +2 -2
  93. data/spec/{object → gorillib/object}/blank_spec.rb +2 -2
  94. data/spec/{object → gorillib/object}/try_dup_spec.rb +2 -2
  95. data/spec/{object → gorillib/object}/try_spec.rb +3 -2
  96. data/spec/gorillib/pathname_spec.rb +114 -0
  97. data/spec/{string → gorillib/string}/constantize_spec.rb +2 -2
  98. data/spec/{string → gorillib/string}/human_spec.rb +2 -2
  99. data/spec/{string → gorillib/string}/inflections_spec.rb +4 -3
  100. data/spec/{string → gorillib/string}/inflector_test_cases.rb +0 -0
  101. data/spec/{string → gorillib/string}/truncate_spec.rb +4 -10
  102. data/spec/gorillib/type/extended_spec.rb +120 -0
  103. data/spec/gorillib/utils/capture_output_spec.rb +71 -0
  104. data/spec/spec_helper.rb +8 -11
  105. data/spec/support/gorillib_test_helpers.rb +66 -0
  106. data/spec/support/hashlike_fuzzing_helper.rb +31 -33
  107. data/spec/support/hashlike_helper.rb +3 -3
  108. data/spec/support/model_test_helpers.rb +81 -0
  109. data/spec/support/shared_examples/included_module.rb +20 -0
  110. metadata +177 -158
  111. data/lib/gorillib/array/average.rb +0 -13
  112. data/lib/gorillib/array/sorted_median.rb +0 -11
  113. data/lib/gorillib/array/sorted_percentile.rb +0 -11
  114. data/lib/gorillib/array/sorted_sample.rb +0 -12
  115. data/lib/gorillib/dsl_object.rb +0 -64
  116. data/lib/gorillib/hash/indifferent_access.rb +0 -207
  117. data/lib/gorillib/hash/tree_merge.rb +0 -4
  118. data/lib/gorillib/hashlike/tree_merge.rb +0 -49
  119. data/lib/gorillib/metaprogramming/cattr_accessor.rb +0 -79
  120. data/lib/gorillib/metaprogramming/mattr_accessor.rb +0 -61
  121. data/lib/gorillib/receiver/active_model_shim.rb +0 -32
  122. data/lib/gorillib/receiver/acts_as_hash.rb +0 -195
  123. data/lib/gorillib/receiver/acts_as_loadable.rb +0 -42
  124. data/lib/gorillib/receiver/locale/en.yml +0 -27
  125. data/lib/gorillib/receiver/tree_diff.rb +0 -74
  126. data/lib/gorillib/receiver/validations.rb +0 -30
  127. data/lib/gorillib/receiver.rb +0 -402
  128. data/lib/gorillib/receiver_model.rb +0 -21
  129. data/lib/gorillib/struct/acts_as_hash.rb +0 -108
  130. data/notes/fancy_hashes_and_receivers.textile +0 -120
  131. data/notes/hash_rdocs.textile +0 -97
  132. data/spec/array/average_spec.rb +0 -24
  133. data/spec/array/sorted_median_spec.rb +0 -18
  134. data/spec/array/sorted_percentile_spec.rb +0 -24
  135. data/spec/array/sorted_sample_spec.rb +0 -28
  136. data/spec/dsl_object_spec.rb +0 -99
  137. data/spec/hash/indifferent_access_spec.rb +0 -391
  138. data/spec/metaprogramming/cattr_accessor_spec.rb +0 -43
  139. data/spec/metaprogramming/mattr_accessor_spec.rb +0 -45
  140. data/spec/receiver/acts_as_hash_spec.rb +0 -295
  141. data/spec/receiver_spec.rb +0 -551
  142. data/spec/struct/acts_as_hash_fuzz_spec.rb +0 -71
  143. data/spec/struct/acts_as_hash_spec.rb +0 -422
@@ -1,207 +0,0 @@
1
- require 'gorillib/hash/keys'
2
-
3
- # This class has dubious semantics and we only have it so that
4
- # people can write <tt>params[:key]</tt> instead of <tt>params['key']</tt>
5
- # and they get the same value for both keys.
6
-
7
- module Gorillib
8
- class HashWithIndifferentAccess < Hash
9
- def extractable_options?
10
- true
11
- end
12
-
13
- def with_indifferent_access
14
- dup
15
- end
16
-
17
- def initialize(constructor = {})
18
- if constructor.is_a?(Hash)
19
- super()
20
- update(constructor)
21
- else
22
- super(constructor)
23
- end
24
- end
25
-
26
- def default(key = nil)
27
- if include?(converted = convert_key(key))
28
- self[converted]
29
- else
30
- super
31
- end
32
- end
33
-
34
- def self.new_from_hash_copying_default(hash)
35
- new(hash).tap do |new_hash|
36
- new_hash.default = hash.default
37
- end
38
- end
39
-
40
- alias_method(:regular_writer, :[]=) unless method_defined?(:regular_writer)
41
- alias_method :regular_update, :update unless method_defined?(:regular_update)
42
-
43
- # Assigns a new value to the hash:
44
- #
45
- # hash = HashWithIndifferentAccess.new
46
- # hash[:key] = "value"
47
- #
48
- def []=(key, value)
49
- regular_writer(convert_key(key), convert_value(value))
50
- end
51
-
52
- alias_method :store, :[]=
53
-
54
- # Updates the instantized hash with values from the second:
55
- #
56
- # hash_1 = HashWithIndifferentAccess.new
57
- # hash_1[:key] = "value"
58
- #
59
- # hash_2 = HashWithIndifferentAccess.new
60
- # hash_2[:key] = "New Value!"
61
- #
62
- # hash_1.update(hash_2) # => {"key"=>"New Value!"}
63
- #
64
- def update(other_hash)
65
- raise TypeError, "can't convert #{other_hash.nil? ? 'nil' : other_hash.class} into Hash" unless other_hash.respond_to?(:each_pair)
66
- if other_hash.is_a? HashWithIndifferentAccess
67
- super(other_hash)
68
- else
69
- other_hash.each_pair{|key, value| regular_writer(convert_key(key), convert_value(value)) }
70
- self
71
- end
72
- end
73
-
74
- alias_method :merge!, :update
75
-
76
- # Checks the hash for a key matching the argument passed in:
77
- #
78
- # hash = HashWithIndifferentAccess.new
79
- # hash["key"] = "value"
80
- # hash.key? :key # => true
81
- # hash.key? "key" # => true
82
- #
83
- def key?(key)
84
- super(convert_key(key))
85
- end
86
-
87
- alias_method :include?, :key?
88
- alias_method :has_key?, :key?
89
- alias_method :member?, :key?
90
-
91
- # Fetches the value for the specified key, same as doing hash[key]
92
- def fetch(key, *extras)
93
- super(convert_key(key), *extras)
94
- end
95
-
96
- # Returns an array of the values at the specified indices:
97
- #
98
- # hash = HashWithIndifferentAccess.new
99
- # hash[:a] = "x"
100
- # hash[:b] = "y"
101
- # hash.values_at("a", "b") # => ["x", "y"]
102
- #
103
- def values_at(*indices)
104
- indices.collect {|key| self[convert_key(key)]}
105
- end
106
-
107
- # Returns an exact copy of the hash.
108
- def dup
109
- self.class.new(self).tap do |new_hash|
110
- new_hash.default = default
111
- end
112
- end
113
-
114
- # Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
115
- # Does not overwrite the existing hash.
116
- def merge(hash)
117
- self.dup.update(hash)
118
- end
119
-
120
- # Performs the opposite of merge, with the keys and values from the first hash taking precedence over the second.
121
- # This overloaded definition prevents returning a regular hash, if reverse_merge is called on a <tt>HashWithDifferentAccess</tt>.
122
- def reverse_merge(other_hash)
123
- super self.class.new_from_hash_copying_default(other_hash)
124
- end
125
-
126
- def reverse_merge!(other_hash)
127
- replace(reverse_merge( other_hash ))
128
- end
129
-
130
- # Removes a specified key from the hash.
131
- def delete(key)
132
- super(convert_key(key))
133
- end
134
-
135
- def stringify_keys!; self end
136
- def stringify_keys; dup end
137
- undef_method :symbolize_keys! if method_defined?(:symbolize_keys!)
138
- def symbolize_keys; to_hash.symbolize_keys end
139
- def to_options!; self end
140
-
141
- # Convert to a Hash with String keys.
142
- def to_hash
143
- Hash.new(default).merge!(self)
144
- end
145
-
146
- def assoc key
147
- key = convert_key(key)
148
- return unless has_key?(key)
149
- [key, self[key]]
150
- end
151
-
152
- def rassoc val
153
- key = key(val) or return
154
- [key, self[key]]
155
- end
156
-
157
- protected
158
- def convert_key(key)
159
- key.kind_of?(Symbol) ? key.to_s : key
160
- end
161
-
162
- def convert_value(value)
163
- if value.is_a? Hash
164
- value.nested_under_indifferent_access
165
- elsif value.is_a?(Array)
166
- value.dup.replace(value.map{|e| convert_value(e) })
167
- else
168
- value
169
- end
170
- end
171
- end
172
-
173
- end
174
-
175
- module Gorillib
176
- class HashWithIndifferentSymbolKeys < Gorillib::HashWithIndifferentAccess
177
-
178
- def convert_key key
179
- return key if key.is_a?(Fixnum)
180
- key.respond_to?(:to_sym) ? key.to_sym : key
181
- end
182
- end
183
- end
184
-
185
- class Hash
186
-
187
- # Returns an +ActiveSupport::HashWithIndifferentAccess+ out of its receiver:
188
- #
189
- # {:a => 1}.with_indifferent_access["a"] # => 1
190
- #
191
- def with_indifferent_access
192
- Gorillib::HashWithIndifferentAccess.new_from_hash_copying_default(self)
193
- end
194
-
195
- # Called when object is nested under an object that receives
196
- # #with_indifferent_access. This method with be called on the current object
197
- # by the enclosing object and is aliased to #with_indifferent_access by
198
- # default. Subclasses of Hash may overwrite this method to return +self+ if
199
- # converting to an +ActiveSupport::HashWithIndifferentAccess+ would not be
200
- # desirable.
201
- #
202
- # b = {:b => 1}
203
- # {:a => b}.with_indifferent_access["a"] # calls b.nested_under_indifferent_access
204
- #
205
- alias nested_under_indifferent_access with_indifferent_access
206
- end
207
-
@@ -1,4 +0,0 @@
1
- require 'gorillib/hashlike/tree_merge'
2
- class Hash
3
- include Gorillib::Hashlike::TreeMerge
4
- end
@@ -1,49 +0,0 @@
1
- module Gorillib
2
- module Hashlike
3
- module TreeMerge
4
-
5
- # Recursively merges hashlike objects
6
- #
7
- # For each key in keys,
8
- # * if block_given? and yield(key,self_val,other_val) returns non-nil, set that
9
- # * if self is missing value for key, receive the attribute.
10
- # * if self's attribute is an Array, append to it.
11
- # * if self's value responds to tree_merge!, deep merge it.
12
- # * if self's value responds_to merge!, merge! it.
13
- # * otherwise, receive the value from other_hash
14
- #
15
- def tree_merge!(other_hash)
16
- return self if other_hash.blank?
17
- [self.keys, other_hash.keys].flatten.uniq.each do |key|
18
- # get other's val if any
19
- if other_hash.has_key?(key.to_sym) then other_val = other_hash[key.to_sym]
20
- elsif other_hash.has_key?(key.to_s) then other_val = other_hash[key.to_s]
21
- else next ; end
22
- # get self val if any
23
- self_val = self[key]
24
- # get block resolved result if any
25
- if block_given? && yield(key, self_val, other_val)
26
- next
27
- end
28
- # p ['hash tree_merge', key, self_val.respond_to?(:tree_merge!), self_val, '***************', other_val]
29
- #
30
- case
31
- when other_val.nil? then next
32
- when (not has_key?(key)) then self[key] = other_val
33
- when self_val.is_a?(Array) then self[key] += other_val
34
- when self_val.respond_to?(:tree_merge!) then self[key] = self_val.tree_merge!(other_val)
35
- when self_val.respond_to?(:merge!) then self[key] = self_val.merge!(other_val)
36
- else self[key] = other_val
37
- end
38
- end
39
- self
40
- end
41
-
42
- end
43
- end
44
- end
45
-
46
-
47
- class Hash
48
- include Gorillib::Hashlike::TreeMerge
49
- end
@@ -1,79 +0,0 @@
1
- require 'gorillib/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
- # Note that unlike +class_attribute+, if a subclass changes the value then that would
7
- # also change the value for parent class. Similarly if parent class changes the value
8
- # then that would change the value of subclasses too.
9
- #
10
- # class Person
11
- # cattr_accessor :hair_colors
12
- # end
13
- #
14
- # Person.hair_colors = [:brown, :black, :blonde, :red]
15
- # Person.hair_colors # => [:brown, :black, :blonde, :red]
16
- # Person.new.hair_colors # => [:brown, :black, :blonde, :red]
17
- #
18
- # To opt out of the instance writer method, pass :instance_writer => false.
19
- # To opt out of the instance reader method, pass :instance_reader => false.
20
- #
21
- # class Person
22
- # cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
23
- # end
24
- #
25
- # Person.new.hair_colors = [:brown] # => NoMethodError
26
- # Person.new.hair_colors # => NoMethodError
27
- class Class
28
- def cattr_reader(*syms)
29
- options = syms.extract_options!
30
- syms.each do |sym|
31
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
32
- unless defined? @@#{sym}
33
- @@#{sym} = nil
34
- end
35
-
36
- def self.#{sym}
37
- @@#{sym}
38
- end
39
- EOS
40
-
41
- unless options[:instance_reader] == false
42
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
43
- def #{sym}
44
- @@#{sym}
45
- end
46
- EOS
47
- end
48
- end
49
- end unless method_defined?(:cattr_reader)
50
-
51
- def cattr_writer(*syms)
52
- options = syms.extract_options!
53
- syms.each do |sym|
54
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
55
- unless defined? @@#{sym}
56
- @@#{sym} = nil
57
- end
58
-
59
- def self.#{sym}=(obj)
60
- @@#{sym} = obj
61
- end
62
- EOS
63
-
64
- unless options[:instance_writer] == false
65
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
66
- def #{sym}=(obj)
67
- @@#{sym} = obj
68
- end
69
- EOS
70
- end
71
- self.send("#{sym}=", yield) if block_given?
72
- end
73
- end unless method_defined?(:cattr_writer)
74
-
75
- def cattr_accessor(*syms, &blk)
76
- cattr_reader(*syms)
77
- cattr_writer(*syms, &blk)
78
- end unless method_defined?(:cattr_accessor)
79
- end
@@ -1,61 +0,0 @@
1
- require 'gorillib/array/extract_options'
2
-
3
- class Module
4
- def mattr_reader(*syms)
5
- options = syms.extract_options!
6
- syms.each do |sym|
7
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
8
- @@#{sym} = nil unless defined? @@#{sym}
9
-
10
- def self.#{sym}
11
- @@#{sym}
12
- end
13
- EOS
14
-
15
- unless options[:instance_reader] == false
16
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
17
- def #{sym}
18
- @@#{sym}
19
- end
20
- EOS
21
- end
22
- end
23
- end unless method_defined?(:mattr_reader)
24
-
25
- def mattr_writer(*syms)
26
- options = syms.extract_options!
27
- syms.each do |sym|
28
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
29
- def self.#{sym}=(obj)
30
- @@#{sym} = obj
31
- end
32
- EOS
33
-
34
- unless options[:instance_writer] == false
35
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
36
- def #{sym}=(obj)
37
- @@#{sym} = obj
38
- end
39
- EOS
40
- end
41
- end
42
- end unless method_defined?(:mattr_writer)
43
-
44
- # Extends the module object with module and instance accessors for class attributes,
45
- # just like the native attr* accessors for instance attributes.
46
- #
47
- # module AppConfiguration
48
- # mattr_accessor :google_api_key
49
- # self.google_api_key = "123456789"
50
- #
51
- # mattr_accessor :paypal_url
52
- # self.paypal_url = "www.sandbox.paypal.com"
53
- # end
54
- #
55
- # AppConfiguration.google_api_key = "overriding the api key!"
56
- def mattr_accessor(*syms)
57
- mattr_reader(*syms)
58
- mattr_writer(*syms)
59
- end unless method_defined?(:mattr_accessor)
60
-
61
- end
@@ -1,32 +0,0 @@
1
- # require 'active_model'
2
-
3
- require 'active_model/deprecated_error_methods'
4
- require 'active_model/errors'
5
- require 'active_model/naming'
6
- require 'active_model/validator'
7
- require 'active_model/translation'
8
- require 'active_model/validations'
9
- require 'active_support/i18n'
10
- I18n.load_path << File.join(File.expand_path(File.dirname(__FILE__)), 'locale/en.yml')
11
-
12
- module Receiver
13
- module ActiveModelShim
14
-
15
- def to_model
16
- self
17
- end
18
-
19
- def new_record?() true end
20
- def destroyed?() false end
21
- def errors
22
- @_errors ||= ActiveModel::Errors.new(self)
23
- end
24
-
25
- def self.included(base)
26
- base.class_eval do
27
- extend ActiveModel::Naming
28
- include ActiveModel::Validations
29
- end
30
- end
31
- end
32
- end
@@ -1,195 +0,0 @@
1
- require 'gorillib/hashlike'
2
-
3
- module Receiver
4
- #
5
- # Makes a Receiver thingie behave mostly like a hash.
6
- #
7
- # By default, the hashlike methods iterate over the receiver attributes:
8
- # instance #keys delegates to self.class.keys which calls
9
- # receiver_attr_names. If you want to filter our add to the keys list, you
10
- # can just override the class-level keys method (and call super, or not):
11
- #
12
- # def self.keys
13
- # super + [:firstname, :lastname] - [:fullname]
14
- # end
15
- #
16
- # All methods are defined naturally on [], []= and has_key? -- if you enjoy
17
- #
18
- #
19
- # in addition to the below, by including Enumerable, this also adds
20
- #
21
- # :each_cons, :each_entry, :each_slice, :each_with_index, :each_with_object,
22
- # :map, :collect, :collect_concat, :entries, :to_a, :flat_map, :inject, :reduce,
23
- # :group_by, :chunk, :cycle, :partition, :reverse_each, :slice_before, :drop,
24
- # :drop_while, :take, :take_while, :detect, :find, :find_all, :find_index, :grep,
25
- # :all?, :any?, :none?, :one?, :first, :count, :zip :max, :max_by, :min, :min_by,
26
- # :minmax, :minmax_by, :sort, :sort_by
27
- #
28
- # As opposed to hash, does *not* define
29
- #
30
- # default, default=, default_proc, default_proc=, shift, flatten, compare_by_identity
31
- # compare_by_identity? rehash
32
- #
33
- module ActsAsHash
34
-
35
- module InstanceMethods
36
-
37
- # Hashlike#[]
38
- #
39
- # Element Reference -- Retrieves the value stored for +key+.
40
- #
41
- # In a normal hash, a default value can be set; none is provided here.
42
- #
43
- # Delegates to self.send(key)
44
- #
45
- # @example
46
- # hsh = { :a => 100, :b => 200 }
47
- # hsh[:a] # => 100
48
- # hsh[:c] # => nil
49
- #
50
- # @param key [Object] key to retrieve
51
- # @return [Object] the value stored for key, nil if missing
52
- #
53
- def [](key)
54
- key = convert_key(key)
55
- self.send(key)
56
- end
57
-
58
- # Hashlike#[]=
59
- # Hashlike#store
60
- #
61
- # Element Assignment -- Associates the value given by +val+ with the key
62
- # given by +key+.
63
- #
64
- # key should not have its value changed while it is in use as a key. In a
65
- # normal hash, a String passed as a key will be duplicated and frozen. No such
66
- # guarantee is provided here
67
- #
68
- # Delegates to self.send("key=", val)
69
- #
70
- # @example
71
- # hsh = { :a => 100, :b => 200 }
72
- # hsh[:a] = 9
73
- # hsh[:c] = 4
74
- # hsh # => { :a => 9, :b => 200, :c => 4 }
75
- #
76
- # hsh[key] = val -> val
77
- # hsh.store(key, val) -> val
78
- #
79
- # @param key [Object] key to associate
80
- # @param val [Object] value to associate it with
81
- # @return [Object]
82
- #
83
- def []=(key, val)
84
- key = convert_key(key)
85
- self.send("#{key}=", val)
86
- end
87
-
88
- # Hashlike#delete
89
- #
90
- # Deletes and returns the value from +hsh+ whose key is equal to +key+. If the
91
- # optional code block is given and the key is not found, pass in the key and
92
- # return the result of +block+.
93
- #
94
- # In a normal hash, a default value can be set; none is provided here.
95
- #
96
- # @example
97
- # hsh = { :a => 100, :b => 200 }
98
- # hsh.delete(:a) # => 100
99
- # hsh.delete(:z) # => nil
100
- # hsh.delete(:z){|el| "#{el} not found" } # => "z not found"
101
- #
102
- # @overload hsh.delete(key) -> val
103
- # @param key [Object] key to remove
104
- # @return [Object, Nil] the removed object, nil if missing
105
- #
106
- # @overload hsh.delete(key){|key| block } -> val
107
- # @param key [Object] key to remove
108
- # @yield [Object] called (with key) if key is missing
109
- # @yieldparam key
110
- # @return [Object, Nil] the removed object, or if missing, the return value
111
- # of the block
112
- #
113
- def delete(key, &block)
114
- key = convert_key(key)
115
- if has_key?(key)
116
- val = self[key]
117
- self.send(:remove_instance_variable, "@#{key}")
118
- val
119
- elsif block_given?
120
- block.call(key)
121
- else
122
- nil
123
- end
124
- end
125
-
126
- # Hashlike#keys
127
- #
128
- # Returns a new array populated with the keys from this hashlike.
129
- #
130
- # @see Hashlike#values.
131
- #
132
- # @example
133
- # hsh = { :a => 100, :b => 200, :c => 300, :d => 400 }
134
- # hsh.keys # => [:a, :b, :c, :d]
135
- #
136
- # @return [Array] list of keys
137
- #
138
- def keys
139
- members & instance_variables.map{|s| convert_key(s[1..-1]) }
140
- end
141
-
142
- def members
143
- self.class.members
144
- end
145
-
146
- #
147
- # Returns a hash with each key set to its associated value.
148
- #
149
- # @example
150
- # my_hshlike = MyHashlike.new
151
- # my_hshlike[:a] = 100; my_hshlike[:b] = 200
152
- # my_hshlike.to_hash # => { :a => 100, :b => 200 }
153
- #
154
- # @return [Hash] a new Hash instance, with each key set to its associated value.
155
- #
156
- def to_hash
157
- {}.tap do |hsh|
158
- each_pair do |key, val|
159
- hsh[key] = val.respond_to?(:to_hash) ? val.to_hash : val
160
- end
161
- end
162
- end
163
-
164
- end
165
-
166
- module ClassMethods
167
- # By default, the hashlike methods iterate over the receiver attributes.
168
- # If you want to filter our add to the keys list, override this method
169
- #
170
- # @example
171
- # def self.keys
172
- # super + [:firstname, :lastname] - [:fullname]
173
- # end
174
- #
175
- def keys
176
- receiver_attr_names
177
- end
178
- end
179
-
180
- protected
181
-
182
- def convert_key(key)
183
- raise ArgumentError, "Keys for #{self.class} must be symbols, strings or respond to #to_sym" unless key.respond_to?(:to_sym)
184
- key.to_sym
185
- end
186
-
187
- def self.included base
188
- base.class_eval do
189
- include Gorillib::Hashlike
190
- extend ClassMethods
191
- include InstanceMethods
192
- end
193
- end
194
- end
195
- end
@@ -1,42 +0,0 @@
1
- module Receiver
2
- #
3
- # adds methods to load and store from json, yaml or magic
4
- #
5
- # This will require 'json' UNLESS you have already included something (so if
6
- # you want to say require 'yajl' then do that first).
7
- #
8
- module ActsAsLoadable
9
-
10
- module ClassMethods
11
- def receive_json stream
12
- receive(JSON.load(stream))
13
- end
14
-
15
- def receive_yaml stream
16
- receive(YAML.load(stream))
17
- end
18
-
19
- #
20
- # The file is loaded with
21
- # * YAML if the filename ends in .yaml or .yml
22
- # * JSON otherwise
23
- #
24
- def receive_from_file filename
25
- stream = File.open(filename)
26
- (filename =~ /.ya?ml$/) ? receive_yaml(stream) : receive_json(stream)
27
- end
28
- end
29
-
30
- def merge_from_file! filename
31
- other_obj = self.class.receive_from_file(filename)
32
- tree_merge! other_obj
33
- end
34
-
35
- # put all the things in ClassMethods at class level
36
- def self.included base
37
- require 'yaml'
38
- require 'json' unless defined?(JSON)
39
- base.extend ClassMethods
40
- end
41
- end
42
- end
@@ -1,27 +0,0 @@
1
- en:
2
- errors:
3
- # The default format to use in full error messages.
4
- format: "%{attribute} %{message}"
5
-
6
- # The values :model, :attribute and :value are always available for interpolation
7
- # The value :count is available when applicable. Can be used for pluralization.
8
- messages:
9
- inclusion: "is not included in the list"
10
- exclusion: "is reserved"
11
- invalid: "is invalid"
12
- confirmation: "doesn't match confirmation"
13
- accepted: "must be accepted"
14
- empty: "can't be empty"
15
- blank: "can't be blank"
16
- too_long: "is too long (maximum is %{count} characters)"
17
- too_short: "is too short (minimum is %{count} characters)"
18
- wrong_length: "is the wrong length (should be %{count} characters)"
19
- not_a_number: "is not a number"
20
- not_an_integer: "must be an integer"
21
- greater_than: "must be greater than %{count}"
22
- greater_than_or_equal_to: "must be greater than or equal to %{count}"
23
- equal_to: "must be equal to %{count}"
24
- less_than: "must be less than %{count}"
25
- less_than_or_equal_to: "must be less than or equal to %{count}"
26
- odd: "must be odd"
27
- even: "must be even"