gorillib 0.4.1pre → 0.4.2pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +13 -10
- data/.rspec +1 -1
- data/.yardopts +1 -0
- data/CHANGELOG.md +47 -0
- data/Gemfile +22 -19
- data/Guardfile +23 -9
- data/README.md +12 -12
- data/Rakefile +29 -40
- data/VERSION +1 -1
- data/examples/benchmark/factories_benchmark.rb +87 -0
- data/examples/builder/ironfan.rb +1 -19
- data/examples/hash/slicing_methods.rb +101 -0
- data/gorillib.gemspec +36 -35
- data/lib/gorillib/array/deep_compact.rb +4 -3
- data/lib/gorillib/array/simple_statistics.rb +76 -0
- data/lib/gorillib/base.rb +0 -1
- data/lib/gorillib/builder.rb +15 -30
- data/lib/gorillib/collection.rb +159 -57
- data/lib/gorillib/collection/model_collection.rb +136 -43
- data/lib/gorillib/datetime/parse.rb +4 -2
- data/lib/gorillib/{array → deprecated/array}/average.rb +0 -0
- data/lib/gorillib/{array → deprecated/array}/random.rb +2 -1
- data/lib/gorillib/{array → deprecated/array}/sorted_median.rb +0 -0
- data/lib/gorillib/{array → deprecated/array}/sorted_percentile.rb +0 -0
- data/lib/gorillib/deprecated/array/sorted_sample.rb +13 -0
- data/lib/gorillib/{metaprogramming → deprecated/metaprogramming}/aliasing.rb +0 -0
- data/lib/gorillib/enumerable/sum.rb +3 -3
- data/lib/gorillib/exception/raisers.rb +92 -22
- data/lib/gorillib/factories.rb +550 -0
- data/lib/gorillib/hash/mash.rb +15 -58
- data/lib/gorillib/hashlike/deep_compact.rb +2 -2
- data/lib/gorillib/hashlike/slice.rb +55 -40
- data/lib/gorillib/model.rb +5 -3
- data/lib/gorillib/model/base.rb +33 -119
- data/lib/gorillib/model/defaults.rb +58 -14
- data/lib/gorillib/model/errors.rb +10 -0
- data/lib/gorillib/model/factories.rb +1 -367
- data/lib/gorillib/model/field.rb +40 -18
- data/lib/gorillib/model/fixup.rb +16 -0
- data/lib/gorillib/model/positional_fields.rb +35 -0
- data/lib/gorillib/model/schema_magic.rb +162 -0
- data/lib/gorillib/model/serialization.rb +1 -2
- data/lib/gorillib/model/serialization/csv.rb +59 -0
- data/lib/gorillib/pathname.rb +19 -8
- data/lib/gorillib/some.rb +2 -0
- data/lib/gorillib/string/constantize.rb +17 -10
- data/lib/gorillib/string/inflector.rb +11 -7
- data/lib/gorillib/type/boolean.rb +40 -0
- data/lib/gorillib/type/extended.rb +76 -40
- data/lib/gorillib/type/url.rb +6 -4
- data/lib/gorillib/utils/console.rb +1 -18
- data/lib/gorillib/utils/edge_cases.rb +18 -0
- data/spec/examples/builder/ironfan_spec.rb +5 -10
- data/spec/gorillib/array/compact_blank_spec.rb +36 -21
- data/spec/gorillib/array/simple_statistics_spec.rb +143 -0
- data/spec/gorillib/builder_spec.rb +16 -20
- data/spec/gorillib/collection_spec.rb +131 -35
- data/spec/gorillib/exception/raisers_spec.rb +39 -0
- data/spec/gorillib/hash/deep_compact_spec.rb +3 -3
- data/spec/gorillib/model/{record/defaults_spec.rb → defaults_spec.rb} +5 -1
- data/spec/gorillib/model/factories_spec.rb +335 -0
- data/spec/gorillib/model/{record/overlay_spec.rb → overlay_spec.rb} +0 -0
- data/spec/gorillib/model/serialization_spec.rb +2 -2
- data/spec/gorillib/model_spec.rb +19 -18
- data/spec/gorillib/pathname_spec.rb +7 -7
- data/spec/gorillib/string/truncate_spec.rb +3 -13
- data/spec/gorillib/type/extended_spec.rb +50 -2
- data/spec/gorillib/utils/capture_output_spec.rb +1 -1
- data/spec/spec_helper.rb +10 -7
- data/spec/support/factory_test_helpers.rb +76 -0
- data/spec/support/gorillib_test_helpers.rb +36 -24
- data/spec/support/model_test_helpers.rb +39 -2
- metadata +86 -51
- data/lib/alt/kernel/call_stack.rb +0 -56
- data/lib/gorillib/array/sorted_sample.rb +0 -12
- data/lib/gorillib/builder/field.rb +0 -5
- data/lib/gorillib/collection/has_collection.rb +0 -31
- data/lib/gorillib/collection/list_collection.rb +0 -58
- data/lib/gorillib/exception/confidence.rb +0 -17
- data/lib/gorillib/io/system_helpers.rb +0 -30
- data/lib/gorillib/model/record_schema.rb +0 -9
- data/lib/gorillib/utils/stub_module.rb +0 -33
- 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/gorillib/metaprogramming/aliasing_spec.rb +0 -180
- data/spec/gorillib/model/record/factories_spec.rb +0 -335
- data/spec/support/kcode_test_helper.rb +0 -16
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'formatador'
|
4
|
+
require 'active_support/core_ext/hash/slice.rb'
|
5
|
+
load File.expand_path('../../lib/gorillib/hashlike/slice.rb', File.dirname(__FILE__))
|
6
|
+
load File.expand_path('../../lib/gorillib/hash/mash.rb', File.dirname(__FILE__))
|
7
|
+
|
8
|
+
# +-----------+-------+---------+-------------+---------------------------+--------------------+
|
9
|
+
# | method | kind | altered | returns | result | receiver |
|
10
|
+
# +-----------+-------+---------+-------------+---------------------------+--------------------+
|
11
|
+
# | select | block | - | copy | {:a=>"A", :c=>"A"} | (unchanged) |
|
12
|
+
# | only | list | - | copy | {:a=>"A", :c=>"A"} | (unchanged) |
|
13
|
+
# | slice | list | - | copy | {:a=>"A", :c=>"A"} | (unchanged) |
|
14
|
+
# | reject | block | - | copy | {:b=>"not A"} | (unchanged) |
|
15
|
+
# | except | list | - | copy | {:b=>"not A"} | (unchanged) |
|
16
|
+
# | select! | block | yes | self or nil | {:a=>"A", :c=>"A"} or nil | {:a=>"A", :c=>"A"} |
|
17
|
+
# | keep_if | block | yes | self | {:a=>"A", :c=>"A"} | {:a=>"A", :c=>"A"} |
|
18
|
+
# | only! | list | yes | self | {:a=>"A", :c=>"A"} | {:a=>"A", :c=>"A"} |
|
19
|
+
# | slice! | list | yes | copy | {:b=>"not A"} | {:a=>"A", :c=>"A"} |
|
20
|
+
# | reject! | block | yes | self or nil | {:b=>"not A"} or nil | {:b=>"not A"} |
|
21
|
+
# | delete_if | block | yes | self | {:b=>"not A"} | {:b=>"not A"} |
|
22
|
+
# | except! | list | yes | self | {:b=>"not A"} | {:b=>"not A"} |
|
23
|
+
# | extract! | list | yes | copy | {:a=>"A", :c=>"A"} | {:b=>"not A"} |
|
24
|
+
# +-----------+-------+---------+-------------+---------------------------+--------------------+
|
25
|
+
|
26
|
+
SLICING_METHODS = [
|
27
|
+
:select, :only, :slice,
|
28
|
+
:reject, :except,
|
29
|
+
:select!, :keep_if, :only!, :slice!,
|
30
|
+
:reject!, :delete_if, :except!, :extract!, ]
|
31
|
+
|
32
|
+
|
33
|
+
class Hashish < Hash
|
34
|
+
include Gorillib::Hashlike::Slice
|
35
|
+
include Gorillib::Hashlike::ExceptOnly
|
36
|
+
end
|
37
|
+
class Mashish < Mash
|
38
|
+
include Gorillib::Hashlike::ExceptOnly
|
39
|
+
end
|
40
|
+
|
41
|
+
EXAMPLE_HASH = { a: 'A', b: 'not A', c: 'A' }.freeze
|
42
|
+
EXAMPLE_MASH = Mash .new.merge!(EXAMPLE_HASH).freeze
|
43
|
+
EXAMPLE_HASHISH = Hashish.new.merge!(EXAMPLE_HASH).freeze
|
44
|
+
EXAMPLE_MASHISH = Mashish.new.merge!(EXAMPLE_HASH).freeze
|
45
|
+
|
46
|
+
# The given set of keys, 'A' -- either as list or block
|
47
|
+
GIVEN_KEYS = [:c, :a]
|
48
|
+
GIVEN_BLK = ->(key,val){ val == 'A' }
|
49
|
+
|
50
|
+
KLASS_COLORS = {Hashish => 'green', Mash => 'blue', Hash => 'red'}
|
51
|
+
|
52
|
+
def colorize(item, choices)
|
53
|
+
color = choices[item] or return item
|
54
|
+
"[#{color}]#{item}[/]"
|
55
|
+
end
|
56
|
+
|
57
|
+
def slicing_method_report(obj, meth)
|
58
|
+
return :split if meth == :split
|
59
|
+
return({ method: meth, result: '(unimplemented)' }) unless obj.respond_to?(meth)
|
60
|
+
hsh = obj.dup
|
61
|
+
kind = (hsh.method(meth).arity == 0) ? :block : :list
|
62
|
+
result = (kind == :block) ? hsh.send(meth, &GIVEN_BLK) : hsh.send(meth, *GIVEN_KEYS)
|
63
|
+
#
|
64
|
+
altered = (hsh == obj)
|
65
|
+
result_str = result.to_s
|
66
|
+
returns = result.equal?(hsh) ? 'self' : 'copy'
|
67
|
+
if [:select!, :reject!].include?(meth)
|
68
|
+
result_str << " or nil"; returns << " or nil"
|
69
|
+
end
|
70
|
+
ret_class = colorize(result.class, KLASS_COLORS)
|
71
|
+
obj_class = colorize(obj.class, KLASS_COLORS)
|
72
|
+
src_loc, _ = hsh.method(meth).source_location
|
73
|
+
provider = case src_loc when /gorillib\/hashlike\/slice/ then 'gorillib' when /activesupp/ then 'activesupp' when nil then 'internal' else 'other' ; end
|
74
|
+
|
75
|
+
{ method: meth, kind: kind, altered: (altered ? '-' : 'yes'),
|
76
|
+
returns: returns, result: result_str, receiver: (altered ? '(unchanged)' : hsh),
|
77
|
+
provider: provider, obj_class: obj_class, ret_class: ret_class }
|
78
|
+
end
|
79
|
+
|
80
|
+
def display_results_table
|
81
|
+
info = SLICING_METHODS.flat_map do |meth|
|
82
|
+
[EXAMPLE_HASH, EXAMPLE_MASH, EXAMPLE_HASHISH, EXAMPLE_MASHISH].flat_map do |obj|
|
83
|
+
slicing_method_report(obj, meth)
|
84
|
+
end + [:split]
|
85
|
+
end
|
86
|
+
Formatador.display_compact_table(info,
|
87
|
+
[:method, :kind, :altered, :returns, :result, :receiver, :provider, :obj_class, :ret_class] )
|
88
|
+
end
|
89
|
+
|
90
|
+
puts
|
91
|
+
puts "Results for hash #{EXAMPLE_HASH.inspect}, of hash.meth(:a, :c) or"
|
92
|
+
puts " hash.meth{|key, val| val == 'A'} as appropriate."
|
93
|
+
puts " Note: select! and reject! act resp. like keep_if and delete_if"
|
94
|
+
puts " but return nil if the contents are unchanged."
|
95
|
+
puts
|
96
|
+
|
97
|
+
display_results_table
|
98
|
+
|
99
|
+
# display_results_table(EXAMPLE_HASHISH)
|
100
|
+
#
|
101
|
+
# display_results_table(EXAMPLE_MASH)
|
data/gorillib.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "gorillib"
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.2pre"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Infochimps"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-08-18"
|
13
13
|
s.description = "Gorillib: infochimps lightweight subset of ruby convenience methods"
|
14
14
|
s.email = "coders@infochimps.org"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -28,32 +28,32 @@ Gem::Specification.new do |s|
|
|
28
28
|
"Rakefile",
|
29
29
|
"TODO.md",
|
30
30
|
"VERSION",
|
31
|
+
"examples/benchmark/factories_benchmark.rb",
|
31
32
|
"examples/builder/ironfan.rb",
|
33
|
+
"examples/hash/slicing_methods.rb",
|
32
34
|
"examples/model/simple.rb",
|
33
35
|
"gorillib.gemspec",
|
34
|
-
"lib/alt/kernel/call_stack.rb",
|
35
36
|
"lib/gorillib.rb",
|
36
|
-
"lib/gorillib/array/average.rb",
|
37
37
|
"lib/gorillib/array/compact_blank.rb",
|
38
38
|
"lib/gorillib/array/deep_compact.rb",
|
39
39
|
"lib/gorillib/array/extract_options.rb",
|
40
|
-
"lib/gorillib/array/
|
41
|
-
"lib/gorillib/array/sorted_median.rb",
|
42
|
-
"lib/gorillib/array/sorted_percentile.rb",
|
43
|
-
"lib/gorillib/array/sorted_sample.rb",
|
40
|
+
"lib/gorillib/array/simple_statistics.rb",
|
44
41
|
"lib/gorillib/array/wrap.rb",
|
45
42
|
"lib/gorillib/base.rb",
|
46
43
|
"lib/gorillib/builder.rb",
|
47
|
-
"lib/gorillib/builder/field.rb",
|
48
44
|
"lib/gorillib/collection.rb",
|
49
|
-
"lib/gorillib/collection/has_collection.rb",
|
50
|
-
"lib/gorillib/collection/list_collection.rb",
|
51
45
|
"lib/gorillib/collection/model_collection.rb",
|
52
46
|
"lib/gorillib/datetime/parse.rb",
|
53
47
|
"lib/gorillib/datetime/to_flat.rb",
|
48
|
+
"lib/gorillib/deprecated/array/average.rb",
|
49
|
+
"lib/gorillib/deprecated/array/random.rb",
|
50
|
+
"lib/gorillib/deprecated/array/sorted_median.rb",
|
51
|
+
"lib/gorillib/deprecated/array/sorted_percentile.rb",
|
52
|
+
"lib/gorillib/deprecated/array/sorted_sample.rb",
|
53
|
+
"lib/gorillib/deprecated/metaprogramming/aliasing.rb",
|
54
54
|
"lib/gorillib/enumerable/sum.rb",
|
55
|
-
"lib/gorillib/exception/confidence.rb",
|
56
55
|
"lib/gorillib/exception/raisers.rb",
|
56
|
+
"lib/gorillib/factories.rb",
|
57
57
|
"lib/gorillib/hash/compact.rb",
|
58
58
|
"lib/gorillib/hash/deep_compact.rb",
|
59
59
|
"lib/gorillib/hash/deep_dup.rb",
|
@@ -73,9 +73,7 @@ Gem::Specification.new do |s|
|
|
73
73
|
"lib/gorillib/hashlike/keys.rb",
|
74
74
|
"lib/gorillib/hashlike/reverse_merge.rb",
|
75
75
|
"lib/gorillib/hashlike/slice.rb",
|
76
|
-
"lib/gorillib/io/system_helpers.rb",
|
77
76
|
"lib/gorillib/logger/log.rb",
|
78
|
-
"lib/gorillib/metaprogramming/aliasing.rb",
|
79
77
|
"lib/gorillib/metaprogramming/class_attribute.rb",
|
80
78
|
"lib/gorillib/metaprogramming/concern.rb",
|
81
79
|
"lib/gorillib/metaprogramming/delegation.rb",
|
@@ -91,11 +89,14 @@ Gem::Specification.new do |s|
|
|
91
89
|
"lib/gorillib/model/errors.rb",
|
92
90
|
"lib/gorillib/model/factories.rb",
|
93
91
|
"lib/gorillib/model/field.rb",
|
92
|
+
"lib/gorillib/model/fixup.rb",
|
94
93
|
"lib/gorillib/model/lint.rb",
|
95
94
|
"lib/gorillib/model/named_schema.rb",
|
96
95
|
"lib/gorillib/model/overlay.rb",
|
97
|
-
"lib/gorillib/model/
|
96
|
+
"lib/gorillib/model/positional_fields.rb",
|
97
|
+
"lib/gorillib/model/schema_magic.rb",
|
98
98
|
"lib/gorillib/model/serialization.rb",
|
99
|
+
"lib/gorillib/model/serialization/csv.rb",
|
99
100
|
"lib/gorillib/model/validate.rb",
|
100
101
|
"lib/gorillib/numeric/clamp.rb",
|
101
102
|
"lib/gorillib/object/blank.rb",
|
@@ -110,12 +111,13 @@ Gem::Specification.new do |s|
|
|
110
111
|
"lib/gorillib/string/inflector.rb",
|
111
112
|
"lib/gorillib/string/simple_inflector.rb",
|
112
113
|
"lib/gorillib/string/truncate.rb",
|
114
|
+
"lib/gorillib/type/boolean.rb",
|
113
115
|
"lib/gorillib/type/extended.rb",
|
114
116
|
"lib/gorillib/type/url.rb",
|
115
117
|
"lib/gorillib/utils/capture_output.rb",
|
116
118
|
"lib/gorillib/utils/console.rb",
|
119
|
+
"lib/gorillib/utils/edge_cases.rb",
|
117
120
|
"lib/gorillib/utils/nuke_constants.rb",
|
118
|
-
"lib/gorillib/utils/stub_module.rb",
|
119
121
|
"notes/HOWTO.md",
|
120
122
|
"notes/bucket.md",
|
121
123
|
"notes/builder.md",
|
@@ -124,15 +126,12 @@ Gem::Specification.new do |s|
|
|
124
126
|
"notes/model-overlay.md",
|
125
127
|
"notes/model.md",
|
126
128
|
"notes/structured-data-classes.md",
|
127
|
-
"spec/array/average_spec.rb",
|
128
|
-
"spec/array/sorted_median_spec.rb",
|
129
|
-
"spec/array/sorted_percentile_spec.rb",
|
130
|
-
"spec/array/sorted_sample_spec.rb",
|
131
129
|
"spec/examples/builder/ironfan_spec.rb",
|
132
130
|
"spec/extlib/hash_spec.rb",
|
133
131
|
"spec/extlib/mash_spec.rb",
|
134
132
|
"spec/gorillib/array/compact_blank_spec.rb",
|
135
133
|
"spec/gorillib/array/extract_options_spec.rb",
|
134
|
+
"spec/gorillib/array/simple_statistics_spec.rb",
|
136
135
|
"spec/gorillib/builder_spec.rb",
|
137
136
|
"spec/gorillib/collection_spec.rb",
|
138
137
|
"spec/gorillib/datetime/parse_spec.rb",
|
@@ -152,14 +151,13 @@ Gem::Specification.new do |s|
|
|
152
151
|
"spec/gorillib/hashlike/hashlike_via_accessors_spec.rb",
|
153
152
|
"spec/gorillib/hashlike_spec.rb",
|
154
153
|
"spec/gorillib/logger/log_spec.rb",
|
155
|
-
"spec/gorillib/metaprogramming/aliasing_spec.rb",
|
156
154
|
"spec/gorillib/metaprogramming/class_attribute_spec.rb",
|
157
155
|
"spec/gorillib/metaprogramming/delegation_spec.rb",
|
158
156
|
"spec/gorillib/metaprogramming/singleton_class_spec.rb",
|
157
|
+
"spec/gorillib/model/defaults_spec.rb",
|
158
|
+
"spec/gorillib/model/factories_spec.rb",
|
159
159
|
"spec/gorillib/model/lint_spec.rb",
|
160
|
-
"spec/gorillib/model/
|
161
|
-
"spec/gorillib/model/record/factories_spec.rb",
|
162
|
-
"spec/gorillib/model/record/overlay_spec.rb",
|
160
|
+
"spec/gorillib/model/overlay_spec.rb",
|
163
161
|
"spec/gorillib/model/serialization_spec.rb",
|
164
162
|
"spec/gorillib/model_spec.rb",
|
165
163
|
"spec/gorillib/numeric/clamp_spec.rb",
|
@@ -175,24 +173,24 @@ Gem::Specification.new do |s|
|
|
175
173
|
"spec/gorillib/type/extended_spec.rb",
|
176
174
|
"spec/gorillib/utils/capture_output_spec.rb",
|
177
175
|
"spec/spec_helper.rb",
|
176
|
+
"spec/support/factory_test_helpers.rb",
|
178
177
|
"spec/support/gorillib_test_helpers.rb",
|
179
178
|
"spec/support/hashlike_fuzzing_helper.rb",
|
180
179
|
"spec/support/hashlike_helper.rb",
|
181
180
|
"spec/support/hashlike_struct_helper.rb",
|
182
181
|
"spec/support/hashlike_via_delegation.rb",
|
183
|
-
"spec/support/kcode_test_helper.rb",
|
184
182
|
"spec/support/matchers/be_array_eql.rb",
|
185
183
|
"spec/support/matchers/be_hash_eql.rb",
|
186
184
|
"spec/support/matchers/enumerate_method.rb",
|
187
185
|
"spec/support/matchers/evaluate_to_true.rb",
|
188
186
|
"spec/support/model_test_helpers.rb"
|
189
187
|
]
|
190
|
-
s.homepage = "
|
191
|
-
s.licenses = ["
|
188
|
+
s.homepage = "https://github.com/infochimps-labs/gorillib"
|
189
|
+
s.licenses = ["Apache 2.0"]
|
192
190
|
s.require_paths = ["lib"]
|
193
|
-
s.rubygems_version = "1.8.
|
191
|
+
s.rubygems_version = "1.8.24"
|
194
192
|
s.summary = "include only what you need. No dependencies, no creep"
|
195
|
-
s.test_files = ["spec/
|
193
|
+
s.test_files = ["spec/examples/builder/ironfan_spec.rb", "spec/extlib/hash_spec.rb", "spec/extlib/mash_spec.rb", "spec/gorillib/array/compact_blank_spec.rb", "spec/gorillib/array/extract_options_spec.rb", "spec/gorillib/array/simple_statistics_spec.rb", "spec/gorillib/builder_spec.rb", "spec/gorillib/collection_spec.rb", "spec/gorillib/datetime/parse_spec.rb", "spec/gorillib/datetime/to_flat_spec.rb", "spec/gorillib/enumerable/sum_spec.rb", "spec/gorillib/exception/raisers_spec.rb", "spec/gorillib/hash/compact_spec.rb", "spec/gorillib/hash/deep_compact_spec.rb", "spec/gorillib/hash/deep_merge_spec.rb", "spec/gorillib/hash/keys_spec.rb", "spec/gorillib/hash/reverse_merge_spec.rb", "spec/gorillib/hash/slice_spec.rb", "spec/gorillib/hash/zip_spec.rb", "spec/gorillib/hashlike/behave_same_as_hash_spec.rb", "spec/gorillib/hashlike/deep_hash_spec.rb", "spec/gorillib/hashlike/hashlike_behavior_spec.rb", "spec/gorillib/hashlike/hashlike_via_accessors_spec.rb", "spec/gorillib/hashlike_spec.rb", "spec/gorillib/logger/log_spec.rb", "spec/gorillib/metaprogramming/class_attribute_spec.rb", "spec/gorillib/metaprogramming/delegation_spec.rb", "spec/gorillib/metaprogramming/singleton_class_spec.rb", "spec/gorillib/model/defaults_spec.rb", "spec/gorillib/model/factories_spec.rb", "spec/gorillib/model/lint_spec.rb", "spec/gorillib/model/overlay_spec.rb", "spec/gorillib/model/serialization_spec.rb", "spec/gorillib/model_spec.rb", "spec/gorillib/numeric/clamp_spec.rb", "spec/gorillib/object/blank_spec.rb", "spec/gorillib/object/try_dup_spec.rb", "spec/gorillib/object/try_spec.rb", "spec/gorillib/pathname_spec.rb", "spec/gorillib/string/constantize_spec.rb", "spec/gorillib/string/human_spec.rb", "spec/gorillib/string/inflections_spec.rb", "spec/gorillib/string/inflector_test_cases.rb", "spec/gorillib/string/truncate_spec.rb", "spec/gorillib/type/extended_spec.rb", "spec/gorillib/utils/capture_output_spec.rb", "spec/spec_helper.rb", "spec/support/factory_test_helpers.rb", "spec/support/gorillib_test_helpers.rb", "spec/support/hashlike_fuzzing_helper.rb", "spec/support/hashlike_helper.rb", "spec/support/hashlike_struct_helper.rb", "spec/support/hashlike_via_delegation.rb", "spec/support/matchers/be_array_eql.rb", "spec/support/matchers/be_hash_eql.rb", "spec/support/matchers/enumerate_method.rb", "spec/support/matchers/evaluate_to_true.rb", "spec/support/model_test_helpers.rb"]
|
196
194
|
|
197
195
|
if s.respond_to? :specification_version then
|
198
196
|
s.specification_version = 3
|
@@ -201,20 +199,23 @@ Gem::Specification.new do |s|
|
|
201
199
|
s.add_runtime_dependency(%q<multi_json>, [">= 1.1"])
|
202
200
|
s.add_development_dependency(%q<bundler>, ["~> 1.1"])
|
203
201
|
s.add_development_dependency(%q<rake>, [">= 0"])
|
204
|
-
s.add_development_dependency(%q<
|
205
|
-
s.add_development_dependency(%q<
|
202
|
+
s.add_development_dependency(%q<yard>, [">= 0.7"])
|
203
|
+
s.add_development_dependency(%q<rspec>, [">= 2.8"])
|
204
|
+
s.add_development_dependency(%q<jeweler>, [">= 1.6"])
|
206
205
|
else
|
207
206
|
s.add_dependency(%q<multi_json>, [">= 1.1"])
|
208
207
|
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
209
208
|
s.add_dependency(%q<rake>, [">= 0"])
|
210
|
-
s.add_dependency(%q<
|
211
|
-
s.add_dependency(%q<
|
209
|
+
s.add_dependency(%q<yard>, [">= 0.7"])
|
210
|
+
s.add_dependency(%q<rspec>, [">= 2.8"])
|
211
|
+
s.add_dependency(%q<jeweler>, [">= 1.6"])
|
212
212
|
end
|
213
213
|
else
|
214
214
|
s.add_dependency(%q<multi_json>, [">= 1.1"])
|
215
215
|
s.add_dependency(%q<bundler>, ["~> 1.1"])
|
216
216
|
s.add_dependency(%q<rake>, [">= 0"])
|
217
|
-
s.add_dependency(%q<
|
218
|
-
s.add_dependency(%q<
|
217
|
+
s.add_dependency(%q<yard>, [">= 0.7"])
|
218
|
+
s.add_dependency(%q<rspec>, [">= 2.8"])
|
219
|
+
s.add_dependency(%q<jeweler>, [">= 1.6"])
|
219
220
|
end
|
220
221
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
require 'set'
|
1
2
|
require 'gorillib/object/blank'
|
2
3
|
|
3
|
-
#
|
4
|
-
# deep_compact! removes all 'blank?' elements in the array in place, recursively
|
5
|
-
#
|
6
4
|
class Array
|
5
|
+
#
|
6
|
+
# deep_compact! removes all 'blank?' elements in the array in place, recursively
|
7
|
+
#
|
7
8
|
def deep_compact!
|
8
9
|
self.map! do |val|
|
9
10
|
val.deep_compact! if val.respond_to?(:deep_compact!)
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Array
|
2
|
+
|
3
|
+
#
|
4
|
+
# The average of my elements.
|
5
|
+
# precondition: Each element must be convertible to a float.
|
6
|
+
#
|
7
|
+
# @return [Float] average of all elements
|
8
|
+
def average
|
9
|
+
return nil if empty?
|
10
|
+
inject(:+) / size.to_f
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# @return the element that fraction of the way along the indexes
|
15
|
+
#
|
16
|
+
# @example halfway point:
|
17
|
+
# [1,4,9,16,25].at_fraction(0.5) # 9
|
18
|
+
#
|
19
|
+
# @example note that indexes are rounded down:
|
20
|
+
# [1,4,9,16,25].at_fraction(0.74999) # 9
|
21
|
+
# [1,4,9,16,25].at_fraction(0.75) # 16
|
22
|
+
#
|
23
|
+
# @example blank array:
|
24
|
+
# [].at_fraction(0.1) # nil
|
25
|
+
#
|
26
|
+
def at_fraction(fraction)
|
27
|
+
raise ArgumentError, "fraction should be between 0.0 and 1.0: got #{fraction.inspect}" unless (0.0 .. 1.0).include?(fraction)
|
28
|
+
return nil if empty?
|
29
|
+
self[ ((size - 1) * Float(fraction)).round ]
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# @return the 1/nth, 2/nth, ... n/nth (last) elements in the array.
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# [1,4,9,16,25,36,49].take_nths(3) # [4, 16, 36]
|
37
|
+
# [ 4,9, 16, 36,49].take_nths(3) # [4, 16, 36]
|
38
|
+
# [1,4,9,16,25,36,49].take_nths(5) # [1, 4, 16, 25, 36]
|
39
|
+
#
|
40
|
+
# @example edge cases
|
41
|
+
# [1,4,9,16,25,36,49].take_nths(99) # [1,4,9,16,25,36,49]
|
42
|
+
# [1,4,9,16,25,36,49].take_nths(1) # [16]
|
43
|
+
# [1,4,9,16,25,36,49].take_nths(0) # []
|
44
|
+
# [].take_nths(3) # []
|
45
|
+
#
|
46
|
+
# The array must be sorted for this to be useful.
|
47
|
+
#
|
48
|
+
def take_nths(num)
|
49
|
+
return [] if empty?
|
50
|
+
(0 .. num-1).map{|step| at_fraction( (step + 0.5)/(num)) }.uniq
|
51
|
+
end
|
52
|
+
|
53
|
+
#
|
54
|
+
# Returns the middle element of odd-sized arrays. For even arrays,
|
55
|
+
# it will return one of the two middle elements. Precisely which is
|
56
|
+
# undefined, except that it will consistently return one or the
|
57
|
+
# other.
|
58
|
+
#
|
59
|
+
# The array must be sorted for this to be useful.
|
60
|
+
#
|
61
|
+
def sorted_median
|
62
|
+
at_fraction(0.5)
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Returns the element at the position closest to the given
|
67
|
+
# percentile. For example, sorted_percentile 0.0 will return the
|
68
|
+
# first element and sorted_percentile 100.0 will return the last
|
69
|
+
# element.
|
70
|
+
#
|
71
|
+
# The array must be sorted for this to be useful.
|
72
|
+
#
|
73
|
+
def sorted_percentile(percentile)
|
74
|
+
at_fraction(percentile / 100.0)
|
75
|
+
end
|
76
|
+
end
|
data/lib/gorillib/base.rb
CHANGED
data/lib/gorillib/builder.rb
CHANGED
@@ -7,12 +7,12 @@ module Gorillib
|
|
7
7
|
extend Gorillib::Concern
|
8
8
|
include Gorillib::Model
|
9
9
|
|
10
|
+
# @return [Object, nil] the return value of the block, or nil if no block given
|
10
11
|
def receive!(*args, &block)
|
11
12
|
super(*args)
|
12
13
|
if block_given?
|
13
14
|
(block.arity == 1) ? block.call(self) : self.instance_eval(&block)
|
14
15
|
end
|
15
|
-
self
|
16
16
|
end
|
17
17
|
|
18
18
|
def getset(field, *args, &block)
|
@@ -35,8 +35,8 @@ module Gorillib
|
|
35
35
|
val = read_attribute(field.name)
|
36
36
|
if val.present?
|
37
37
|
# existing item: update it with args and block
|
38
|
-
val.receive!(*args, &block) if args.present?
|
39
|
-
elsif attrs.blank?
|
38
|
+
val.receive!(*args, &block) if args.present? or block_given?
|
39
|
+
elsif attrs.blank? and not block_given?
|
40
40
|
# missing item (read): return nil
|
41
41
|
return nil
|
42
42
|
else
|
@@ -72,7 +72,9 @@ module Gorillib
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def set_collection_item(plural_name, item_key, item)
|
75
|
-
collection_of(plural_name)
|
75
|
+
collection = collection_of(plural_name)
|
76
|
+
collection[item_key] = item
|
77
|
+
collection[item_key]
|
76
78
|
end
|
77
79
|
|
78
80
|
def has_collection_item?(plural_name, item_key)
|
@@ -84,13 +86,11 @@ module Gorillib
|
|
84
86
|
end
|
85
87
|
|
86
88
|
def to_key
|
87
|
-
self.
|
89
|
+
self.send(key_method)
|
88
90
|
end
|
89
91
|
|
90
|
-
def
|
91
|
-
attrs.delete(:owner)
|
92
|
-
# detailed ? str : ([str[0..-2], " #{to_key}>"].join)
|
93
|
-
str = super(detailed, attrs)
|
92
|
+
def to_inspectable
|
93
|
+
super.tap{|attrs| attrs.delete(:owner) }
|
94
94
|
end
|
95
95
|
|
96
96
|
def collection_of(plural_name)
|
@@ -106,10 +106,11 @@ module Gorillib
|
|
106
106
|
def member(field_name, type, options={})
|
107
107
|
field(field_name, type, {:field_type => ::Gorillib::Builder::MemberField}.merge(options))
|
108
108
|
end
|
109
|
+
|
110
|
+
# FIXME: this interface is borked -- it should not take the item_type in the second slot.
|
109
111
|
def collection(field_name, item_type, options={})
|
110
|
-
|
111
|
-
:item_type => item_type,
|
112
|
-
:field_type => ::Gorillib::Builder::CollectionField}.merge(options))
|
112
|
+
super(field_name, Gorillib::ModelCollection, {
|
113
|
+
:item_type => item_type, :field_type => ::Gorillib::Builder::GetsetCollectionField }.merge(options))
|
113
114
|
end
|
114
115
|
|
115
116
|
protected
|
@@ -141,20 +142,6 @@ module Gorillib
|
|
141
142
|
end
|
142
143
|
end
|
143
144
|
|
144
|
-
def define_collection_receiver(field)
|
145
|
-
plural_name = field.name; item_type = field.item_type; field_type = field.type
|
146
|
-
define_meta_module_method("receive_#{plural_name}", true) do |coll, &block|
|
147
|
-
begin
|
148
|
-
if coll.is_a?(field_type)
|
149
|
-
write_attribute(plural_name, coll)
|
150
|
-
else
|
151
|
-
read_attribute(plural_name).receive!(coll, &block)
|
152
|
-
end
|
153
|
-
self
|
154
|
-
rescue StandardError => err ; err.polish("#{self.class} #{plural_name} c[#{item_type}] on #{args}'") rescue nil ; raise ; end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
145
|
def define_collection_tester(field)
|
159
146
|
plural_name = field.plural_name
|
160
147
|
define_meta_module_method("has_#{field.singular_name}?", field.visibility(:collection_tester)) do |item_key|
|
@@ -223,9 +210,8 @@ module Gorillib
|
|
223
210
|
end
|
224
211
|
end
|
225
212
|
|
226
|
-
class
|
213
|
+
class GetsetCollectionField < ::Gorillib::Model::SimpleCollectionField
|
227
214
|
field :singular_name, Symbol, :default => ->{ Gorillib::Inflector.singularize(name.to_s).to_sym }
|
228
|
-
field :item_type, Class, :default => Whatever
|
229
215
|
|
230
216
|
self.visibilities = visibilities.merge(:writer => false, :tester => false,
|
231
217
|
:collection_getset => :public, :collection_tester => true)
|
@@ -236,8 +222,6 @@ module Gorillib
|
|
236
222
|
end
|
237
223
|
|
238
224
|
def inscribe_methods(model)
|
239
|
-
item_type = self.item_type
|
240
|
-
self.default = ->{ Gorillib::ModelCollection.new(nil, item_type) }
|
241
225
|
raise "Plural and singular names must differ: #{self.plural_name}" if (singular_name == plural_name)
|
242
226
|
#
|
243
227
|
@visibilities[:writer] = false
|
@@ -249,6 +233,7 @@ module Gorillib
|
|
249
233
|
model.__send__(:define_collection_tester, self)
|
250
234
|
end
|
251
235
|
end
|
236
|
+
CollectionField = GetsetCollectionField
|
252
237
|
|
253
238
|
end
|
254
239
|
end
|