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.
- data/.gitignore +1 -0
- data/.rspec +1 -2
- data/.yardopts +9 -0
- data/{CHANGELOG.textile → CHANGELOG.md} +35 -9
- data/Gemfile +21 -14
- data/Guardfile +19 -0
- data/{LICENSE.textile → LICENSE.md} +43 -29
- data/README.md +47 -52
- data/Rakefile +31 -30
- data/TODO.md +32 -0
- data/VERSION +1 -1
- data/examples/builder/ironfan.rb +133 -0
- data/examples/model/simple.rb +17 -0
- data/gorillib.gemspec +106 -86
- data/lib/alt/kernel/call_stack.rb +56 -0
- data/lib/gorillib/array/wrap.rb +53 -0
- data/lib/gorillib/base.rb +3 -3
- data/lib/gorillib/builder/field.rb +5 -0
- data/lib/gorillib/builder.rb +260 -0
- data/lib/gorillib/collection/has_collection.rb +31 -0
- data/lib/gorillib/collection.rb +129 -0
- data/lib/gorillib/configurable.rb +28 -0
- data/lib/gorillib/datetime/{flat.rb → to_flat.rb} +0 -0
- data/lib/gorillib/exception/confidence.rb +17 -0
- data/lib/gorillib/exception/raisers.rb +78 -0
- data/lib/gorillib/hash/mash.rb +202 -0
- data/lib/gorillib/hashlike/slice.rb +53 -19
- data/lib/gorillib/hashlike.rb +5 -3
- data/lib/gorillib/io/system_helpers.rb +30 -0
- data/lib/gorillib/logger/log.rb +18 -0
- data/lib/gorillib/metaprogramming/concern.rb +124 -0
- data/lib/gorillib/model/active_model_conversion.rb +68 -0
- data/lib/gorillib/model/active_model_naming.rb +87 -0
- data/lib/gorillib/model/active_model_shim.rb +33 -0
- data/lib/gorillib/model/base.rb +341 -0
- data/lib/gorillib/model/defaults.rb +71 -0
- data/lib/gorillib/model/errors.rb +14 -0
- data/lib/gorillib/model/factories.rb +372 -0
- data/lib/gorillib/model/field.rb +146 -0
- data/lib/gorillib/model/named_schema.rb +53 -0
- data/lib/gorillib/{struct/hashlike_iteration.rb → model/overlay.rb} +0 -0
- data/lib/gorillib/model/record_schema.rb +9 -0
- data/lib/gorillib/model/serialization.rb +23 -0
- data/lib/gorillib/model/validate.rb +22 -0
- data/lib/gorillib/model.rb +23 -0
- data/lib/gorillib/pathname.rb +78 -0
- data/lib/gorillib/{serialization.rb → serialization/to_wire.rb} +0 -0
- data/lib/gorillib/some.rb +11 -9
- data/lib/gorillib/string/constantize.rb +21 -14
- data/lib/gorillib/string/inflections.rb +6 -76
- data/lib/gorillib/string/inflector.rb +192 -0
- data/lib/gorillib/string/simple_inflector.rb +267 -0
- data/lib/gorillib/type/extended.rb +52 -0
- data/lib/gorillib/utils/capture_output.rb +28 -0
- data/lib/gorillib/utils/console.rb +131 -0
- data/lib/gorillib/utils/nuke_constants.rb +9 -0
- data/lib/gorillib/utils/stub_module.rb +33 -0
- data/spec/examples/builder/ironfan_spec.rb +37 -0
- data/spec/extlib/hash_spec.rb +64 -0
- data/spec/extlib/mash_spec.rb +312 -0
- data/spec/{array → gorillib/array}/compact_blank_spec.rb +2 -2
- data/spec/{array → gorillib/array}/extract_options_spec.rb +2 -2
- data/spec/gorillib/builder_spec.rb +187 -0
- data/spec/gorillib/collection_spec.rb +20 -0
- data/spec/gorillib/configurable_spec.rb +62 -0
- data/spec/{datetime → gorillib/datetime}/parse_spec.rb +3 -3
- data/spec/{datetime/flat_spec.rb → gorillib/datetime/to_flat_spec.rb} +4 -4
- data/spec/{enumerable → gorillib/enumerable}/sum_spec.rb +5 -5
- data/spec/gorillib/exception/raisers_spec.rb +60 -0
- data/spec/{hash → gorillib/hash}/compact_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/deep_compact_spec.rb +3 -3
- data/spec/{hash → gorillib/hash}/deep_merge_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/keys_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/reverse_merge_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/slice_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/zip_spec.rb +2 -2
- data/spec/{hashlike → gorillib/hashlike}/behave_same_as_hash_spec.rb +6 -3
- data/spec/{hashlike → gorillib/hashlike}/deep_hash_spec.rb +2 -2
- data/spec/{hashlike → gorillib/hashlike}/hashlike_behavior_spec.rb +32 -30
- data/spec/{hashlike → gorillib/hashlike}/hashlike_via_accessors_spec.rb +3 -3
- data/spec/{hashlike_spec.rb → gorillib/hashlike_spec.rb} +3 -3
- data/spec/{logger → gorillib/logger}/log_spec.rb +2 -2
- data/spec/{metaprogramming → gorillib/metaprogramming}/aliasing_spec.rb +3 -3
- data/spec/{metaprogramming → gorillib/metaprogramming}/class_attribute_spec.rb +3 -3
- data/spec/{metaprogramming → gorillib/metaprogramming}/delegation_spec.rb +3 -3
- data/spec/{metaprogramming → gorillib/metaprogramming}/singleton_class_spec.rb +3 -3
- data/spec/gorillib/model/record/defaults_spec.rb +108 -0
- data/spec/gorillib/model/record/factories_spec.rb +321 -0
- data/spec/gorillib/model/record/overlay_spec.rb +46 -0
- data/spec/gorillib/model/serialization_spec.rb +48 -0
- data/spec/gorillib/model_spec.rb +281 -0
- data/spec/{numeric → gorillib/numeric}/clamp_spec.rb +2 -2
- data/spec/{object → gorillib/object}/blank_spec.rb +2 -2
- data/spec/{object → gorillib/object}/try_dup_spec.rb +2 -2
- data/spec/{object → gorillib/object}/try_spec.rb +3 -2
- data/spec/gorillib/pathname_spec.rb +114 -0
- data/spec/{string → gorillib/string}/constantize_spec.rb +2 -2
- data/spec/{string → gorillib/string}/human_spec.rb +2 -2
- data/spec/{string → gorillib/string}/inflections_spec.rb +4 -3
- data/spec/{string → gorillib/string}/inflector_test_cases.rb +0 -0
- data/spec/{string → gorillib/string}/truncate_spec.rb +4 -10
- data/spec/gorillib/type/extended_spec.rb +120 -0
- data/spec/gorillib/utils/capture_output_spec.rb +71 -0
- data/spec/spec_helper.rb +8 -11
- data/spec/support/gorillib_test_helpers.rb +66 -0
- data/spec/support/hashlike_fuzzing_helper.rb +31 -33
- data/spec/support/hashlike_helper.rb +3 -3
- data/spec/support/model_test_helpers.rb +81 -0
- data/spec/support/shared_examples/included_module.rb +20 -0
- metadata +177 -158
- data/lib/gorillib/array/average.rb +0 -13
- data/lib/gorillib/array/sorted_median.rb +0 -11
- data/lib/gorillib/array/sorted_percentile.rb +0 -11
- data/lib/gorillib/array/sorted_sample.rb +0 -12
- data/lib/gorillib/dsl_object.rb +0 -64
- data/lib/gorillib/hash/indifferent_access.rb +0 -207
- data/lib/gorillib/hash/tree_merge.rb +0 -4
- data/lib/gorillib/hashlike/tree_merge.rb +0 -49
- data/lib/gorillib/metaprogramming/cattr_accessor.rb +0 -79
- data/lib/gorillib/metaprogramming/mattr_accessor.rb +0 -61
- data/lib/gorillib/receiver/active_model_shim.rb +0 -32
- data/lib/gorillib/receiver/acts_as_hash.rb +0 -195
- data/lib/gorillib/receiver/acts_as_loadable.rb +0 -42
- data/lib/gorillib/receiver/locale/en.yml +0 -27
- data/lib/gorillib/receiver/tree_diff.rb +0 -74
- data/lib/gorillib/receiver/validations.rb +0 -30
- data/lib/gorillib/receiver.rb +0 -402
- data/lib/gorillib/receiver_model.rb +0 -21
- data/lib/gorillib/struct/acts_as_hash.rb +0 -108
- data/notes/fancy_hashes_and_receivers.textile +0 -120
- data/notes/hash_rdocs.textile +0 -97
- data/spec/array/average_spec.rb +0 -24
- data/spec/array/sorted_median_spec.rb +0 -18
- data/spec/array/sorted_percentile_spec.rb +0 -24
- data/spec/array/sorted_sample_spec.rb +0 -28
- data/spec/dsl_object_spec.rb +0 -99
- data/spec/hash/indifferent_access_spec.rb +0 -391
- data/spec/metaprogramming/cattr_accessor_spec.rb +0 -43
- data/spec/metaprogramming/mattr_accessor_spec.rb +0 -45
- data/spec/receiver/acts_as_hash_spec.rb +0 -295
- data/spec/receiver_spec.rb +0 -551
- data/spec/struct/acts_as_hash_fuzz_spec.rb +0 -71
- 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,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"
|