gorillib 0.4.1pre → 0.4.2pre

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 (89) hide show
  1. data/.gitignore +13 -10
  2. data/.rspec +1 -1
  3. data/.yardopts +1 -0
  4. data/CHANGELOG.md +47 -0
  5. data/Gemfile +22 -19
  6. data/Guardfile +23 -9
  7. data/README.md +12 -12
  8. data/Rakefile +29 -40
  9. data/VERSION +1 -1
  10. data/examples/benchmark/factories_benchmark.rb +87 -0
  11. data/examples/builder/ironfan.rb +1 -19
  12. data/examples/hash/slicing_methods.rb +101 -0
  13. data/gorillib.gemspec +36 -35
  14. data/lib/gorillib/array/deep_compact.rb +4 -3
  15. data/lib/gorillib/array/simple_statistics.rb +76 -0
  16. data/lib/gorillib/base.rb +0 -1
  17. data/lib/gorillib/builder.rb +15 -30
  18. data/lib/gorillib/collection.rb +159 -57
  19. data/lib/gorillib/collection/model_collection.rb +136 -43
  20. data/lib/gorillib/datetime/parse.rb +4 -2
  21. data/lib/gorillib/{array → deprecated/array}/average.rb +0 -0
  22. data/lib/gorillib/{array → deprecated/array}/random.rb +2 -1
  23. data/lib/gorillib/{array → deprecated/array}/sorted_median.rb +0 -0
  24. data/lib/gorillib/{array → deprecated/array}/sorted_percentile.rb +0 -0
  25. data/lib/gorillib/deprecated/array/sorted_sample.rb +13 -0
  26. data/lib/gorillib/{metaprogramming → deprecated/metaprogramming}/aliasing.rb +0 -0
  27. data/lib/gorillib/enumerable/sum.rb +3 -3
  28. data/lib/gorillib/exception/raisers.rb +92 -22
  29. data/lib/gorillib/factories.rb +550 -0
  30. data/lib/gorillib/hash/mash.rb +15 -58
  31. data/lib/gorillib/hashlike/deep_compact.rb +2 -2
  32. data/lib/gorillib/hashlike/slice.rb +55 -40
  33. data/lib/gorillib/model.rb +5 -3
  34. data/lib/gorillib/model/base.rb +33 -119
  35. data/lib/gorillib/model/defaults.rb +58 -14
  36. data/lib/gorillib/model/errors.rb +10 -0
  37. data/lib/gorillib/model/factories.rb +1 -367
  38. data/lib/gorillib/model/field.rb +40 -18
  39. data/lib/gorillib/model/fixup.rb +16 -0
  40. data/lib/gorillib/model/positional_fields.rb +35 -0
  41. data/lib/gorillib/model/schema_magic.rb +162 -0
  42. data/lib/gorillib/model/serialization.rb +1 -2
  43. data/lib/gorillib/model/serialization/csv.rb +59 -0
  44. data/lib/gorillib/pathname.rb +19 -8
  45. data/lib/gorillib/some.rb +2 -0
  46. data/lib/gorillib/string/constantize.rb +17 -10
  47. data/lib/gorillib/string/inflector.rb +11 -7
  48. data/lib/gorillib/type/boolean.rb +40 -0
  49. data/lib/gorillib/type/extended.rb +76 -40
  50. data/lib/gorillib/type/url.rb +6 -4
  51. data/lib/gorillib/utils/console.rb +1 -18
  52. data/lib/gorillib/utils/edge_cases.rb +18 -0
  53. data/spec/examples/builder/ironfan_spec.rb +5 -10
  54. data/spec/gorillib/array/compact_blank_spec.rb +36 -21
  55. data/spec/gorillib/array/simple_statistics_spec.rb +143 -0
  56. data/spec/gorillib/builder_spec.rb +16 -20
  57. data/spec/gorillib/collection_spec.rb +131 -35
  58. data/spec/gorillib/exception/raisers_spec.rb +39 -0
  59. data/spec/gorillib/hash/deep_compact_spec.rb +3 -3
  60. data/spec/gorillib/model/{record/defaults_spec.rb → defaults_spec.rb} +5 -1
  61. data/spec/gorillib/model/factories_spec.rb +335 -0
  62. data/spec/gorillib/model/{record/overlay_spec.rb → overlay_spec.rb} +0 -0
  63. data/spec/gorillib/model/serialization_spec.rb +2 -2
  64. data/spec/gorillib/model_spec.rb +19 -18
  65. data/spec/gorillib/pathname_spec.rb +7 -7
  66. data/spec/gorillib/string/truncate_spec.rb +3 -13
  67. data/spec/gorillib/type/extended_spec.rb +50 -2
  68. data/spec/gorillib/utils/capture_output_spec.rb +1 -1
  69. data/spec/spec_helper.rb +10 -7
  70. data/spec/support/factory_test_helpers.rb +76 -0
  71. data/spec/support/gorillib_test_helpers.rb +36 -24
  72. data/spec/support/model_test_helpers.rb +39 -2
  73. metadata +86 -51
  74. data/lib/alt/kernel/call_stack.rb +0 -56
  75. data/lib/gorillib/array/sorted_sample.rb +0 -12
  76. data/lib/gorillib/builder/field.rb +0 -5
  77. data/lib/gorillib/collection/has_collection.rb +0 -31
  78. data/lib/gorillib/collection/list_collection.rb +0 -58
  79. data/lib/gorillib/exception/confidence.rb +0 -17
  80. data/lib/gorillib/io/system_helpers.rb +0 -30
  81. data/lib/gorillib/model/record_schema.rb +0 -9
  82. data/lib/gorillib/utils/stub_module.rb +0 -33
  83. data/spec/array/average_spec.rb +0 -24
  84. data/spec/array/sorted_median_spec.rb +0 -18
  85. data/spec/array/sorted_percentile_spec.rb +0 -24
  86. data/spec/array/sorted_sample_spec.rb +0 -28
  87. data/spec/gorillib/metaprogramming/aliasing_spec.rb +0 -180
  88. data/spec/gorillib/model/record/factories_spec.rb +0 -335
  89. data/spec/support/kcode_test_helper.rb +0 -16
@@ -6,42 +6,9 @@ class Hash
6
6
  #
7
7
  # @return [Mash] This hash as a Mash for string or symbol key access.
8
8
  def to_mash
9
- hash = Mash.new(self)
10
- hash.default = default
11
- hash
12
- end
13
-
14
- ##
15
- # Create a hash with *only* key/value pairs in receiver and +allowed+
16
- #
17
- # { :one => 1, :two => 2, :three => 3 }.only(:one) #=> { :one => 1 }
18
- #
19
- # @param allowed [Array[String, Symbol]] The hash keys to include.
20
- #
21
- # @return [Hash] A new hash with only the selected keys.
22
- #
23
- # @api public
24
- def only(*allowed)
25
- hash = {}
26
- allowed.each {|k| hash[k] = self[k] if self.has_key?(k) }
27
- hash
28
- end
29
-
30
- ##
31
- # Create a hash with all key/value pairs in receiver *except* +rejected+
32
- #
33
- # { :one => 1, :two => 2, :three => 3 }.except(:one)
34
- # #=> { :two => 2, :three => 3 }
35
- #
36
- # @param rejected [Array[String, Symbol]] The hash keys to exclude.
37
- #
38
- # @return [Hash] A new hash without the selected keys.
39
- #
40
- # @api public
41
- def except(*rejected)
42
- hash = self.dup
43
- rejected.each {|k| hash.delete(k) }
44
- hash
9
+ hsh = Mash.new(self)
10
+ hsh.default = default
11
+ hsh
45
12
  end
46
13
  end
47
14
 
@@ -109,17 +76,17 @@ class Mash < Hash
109
76
  super(convert_key(key))
110
77
  end
111
78
 
112
- # def include? def has_key? def member?
113
79
  alias_method :include?, :key?
114
80
  alias_method :has_key?, :key?
115
- alias_method :member?, :key?
81
+ alias_method :member?, :key?
116
82
 
117
83
  # @param <Object> key The key to fetch. This will be run through convert_key.
118
- # @param <Array> extras Default value.
84
+ # @param <Array> args Default value.
85
+ # @yield Default block
119
86
  #
120
87
  # @return [Object] The value at key or the default value.
121
- def fetch(key, *extras)
122
- super(convert_key(key), *extras)
88
+ def fetch(key, *args, &block)
89
+ super(convert_key(key), *args, &block)
123
90
  end
124
91
 
125
92
  # @param indices [Array]
@@ -127,7 +94,7 @@ class Mash < Hash
127
94
  #
128
95
  # @return [Array] The values at each of the provided keys
129
96
  def values_at(*indices)
130
- indices.collect {|key| self[convert_key(key)]}
97
+ indices.map{|key| self[convert_key(key)] }
131
98
  end
132
99
 
133
100
  # @param hash<Hash> The hash to merge with the mash.
@@ -143,17 +110,6 @@ class Mash < Hash
143
110
  super(convert_key(key))
144
111
  end
145
112
 
146
- # @param [Array[(String, Symbol)]] rejected The mash keys to exclude.
147
- #
148
- # @return [Mash] A new mash without the selected keys.
149
- #
150
- # @example
151
- # { :one => 1, :two => 2, :three => 3 }.except(:one)
152
- # #=> { "two" => 2, "three" => 3 }
153
- def except(*rejected)
154
- super(*rejected.map {|k| convert_key(k)})
155
- end
156
-
157
113
  # Used to provide the same interface as Hash.
158
114
  #
159
115
  # @return [Mash] This mash unchanged.
@@ -161,9 +117,9 @@ class Mash < Hash
161
117
 
162
118
  # @return [Hash] The mash as a Hash with symbolized keys.
163
119
  def symbolize_keys
164
- h = Hash.new(default)
165
- each { |key, val| h[key.to_sym] = val }
166
- h
120
+ hsh = Hash.new(default)
121
+ each{|key, val| hsh[key.to_sym] = val }
122
+ hsh
167
123
  end
168
124
 
169
125
  # @return [Hash] The mash as a Hash with string keys.
@@ -171,7 +127,8 @@ class Mash < Hash
171
127
  Hash.new(default).merge(self)
172
128
  end
173
129
 
174
- protected
130
+ protected
131
+
175
132
  # @param key [Object] The key to convert.
176
133
  #
177
134
  # @return [Object]
@@ -194,7 +151,7 @@ class Mash < Hash
194
151
  if value.class == Hash
195
152
  value.to_mash
196
153
  elsif value.is_a?(Array)
197
- value.collect { |e| convert_value(e) }
154
+ value.map{|e| convert_value(e) }
198
155
  else
199
156
  value
200
157
  end
@@ -7,9 +7,9 @@ module Gorillib
7
7
  # deep_compact! removes all keys with 'blank?' values in the hash, in place, recursively
8
8
  #
9
9
  def deep_compact!
10
- self.each do |key, val|
10
+ each_pair do |key, val|
11
11
  val.deep_compact! if val.respond_to?(:deep_compact!)
12
- self.delete(key) if val.blank?
12
+ delete(key) if val.blank?
13
13
  end
14
14
  self
15
15
  end
@@ -1,30 +1,31 @@
1
+ require 'set'
1
2
  module Gorillib
2
3
  module Hashlike
3
4
  module Slice
4
- # Slice a hash to include only the given allowed_keys.
5
- #
6
- # @return the sliced hash
5
+
6
+ # Returns a copy having only the given keys
7
7
  #
8
8
  # @example limit an options hash to valid keys before passing to a method:
9
9
  # def search(criteria = {})
10
- # assert_valid_keys(:mass, :velocity, :time)
10
+ # assert_valid_keys(:mass, :velocity, :time) # gorillib/hash/keys
11
11
  # end
12
12
  # search(options.slice(:mass, :velocity, :time))
13
13
  #
14
- # If you have an array of keys you want to limit to, you should splat them:
14
+ # If you have an array of keys you want to limit to, splat them:
15
15
  #
16
16
  # valid_keys = [:mass, :velocity, :time]
17
17
  # search(options.slice(*valid_keys))
18
- def slice(*allowed_keys)
19
- allowed_keys = allowed_keys.map!{|key| convert_key(key) } if respond_to?(:convert_key)
18
+ #
19
+ # @return key/value pairs for keys in self and allowed
20
+ def slice(*allowed)
21
+ allowed.map!{|key| convert_key(key) } if respond_to?(:convert_key, true)
20
22
  hash = self.class.new
21
- allowed_keys.each{|k| hash[k] = self[k] if has_key?(k) }
23
+ allowed.each{|key| hash[key] = self[key] if has_key?(key) }
22
24
  hash
23
- end unless method_defined?(:slice)
25
+ end
24
26
 
25
- # Replace the hash with only the given allowed_keys.
26
- #
27
- # @return a hash containing the removed key/value pairs
27
+ # Retains only the given keys.
28
+ # Returns a copy containing the removed key/value pairs.
28
29
  #
29
30
  # @example
30
31
  # hsh = {:a => 1, :b => 2, :c => 3, :d => 4}
@@ -32,17 +33,17 @@ module Gorillib
32
33
  # # => {:c => 3, :d =>4}
33
34
  # hsh
34
35
  # # => {:a => 1, :b => 2}
35
- def slice!(*allowed_keys)
36
- allowed_keys = allowed_keys.map!{|key| convert_key(key) } if respond_to?(:convert_key)
37
- omit = slice(*self.keys - allowed_keys)
38
- hash = slice(*allowed_keys)
36
+ #
37
+ # @return the removed key/value pairs
38
+ def slice!(*allowed)
39
+ allowed.map!{|key| convert_key(key) } if respond_to?(:convert_key, true)
40
+ omit = slice(*self.keys - allowed)
41
+ hash = slice(*allowed)
39
42
  replace(hash)
40
43
  omit
41
- end unless method_defined?(:slice!)
44
+ end
42
45
 
43
- # Removes the given allowed_keys from the hash
44
- #
45
- # @return a hash containing the removed key/value pairs
46
+ # Removes and returns the key/value pairs matching the given keys.
46
47
  #
47
48
  # @example
48
49
  # hsh = {:a => 1, :b => 2, :c => 3, :d => 4}
@@ -50,50 +51,64 @@ module Gorillib
50
51
  # # => {:a => 1, :b => 2}
51
52
  # hsh
52
53
  # # => {:c => 3, :d =>4}
53
- def extract!(*allowed_keys)
54
- slice!(*self.keys - allowed_keys)
55
- end unless method_defined?(:extract!)
54
+ #
55
+ # @return a copy containing the removed key/value pairs
56
+ def extract!(*allowed)
57
+ slice!(* self.keys-allowed)
58
+ end
56
59
 
57
- # Return a hash that includes everything but the given keys.
60
+ # end
61
+ # module ExceptOnly
62
+
63
+ # Return a copy that excludes the given keys
58
64
  #
59
65
  # @example Exclude a blacklist of parameters
60
66
  # @person.update_attributes(params[:person].except(:admin))
61
67
  #
62
- # If the receiver responds to +convert_key+, the method is called on each of the
63
- # arguments. This allows +except+ to play nice with hashes with indifferent access
64
- # for instance:
68
+ # If the receiver responds to +convert_key+, the method is called on each
69
+ # of the arguments. This allows +except+ to play nice with hashes with
70
+ # indifferent access for instance:
65
71
  #
66
72
  # @example mash, hash, it does the right thing:
67
73
  # {:a => 1}.to_mash.except(:a) # => {}
68
74
  # {:a => 1}.to_mash.except('a') # => {}
69
75
  #
70
- def except(*keys)
71
- dup.except!(*keys)
76
+ def except(*rejected)
77
+ dup.except!(*rejected)
72
78
  end
73
79
 
74
- # Replaces the hash without the given keys.
75
- def except!(*keys)
76
- keys.each{|key| delete(key) }
80
+ # Modifies the hash to exclude the given keys
81
+ # @see #except
82
+ #
83
+ # @return self
84
+ def except!(*rejected)
85
+ rejected.each{|key| delete(key) }
77
86
  self
78
87
  end
79
88
 
89
+ # Return a copy having only the given keys
90
+ #
91
+ # @example Limit a set of parameters to everything but a few known toggles:
92
+ # { :one => 1, :two => 2, :three => 3 }.only(:one) #=> { :one => 1 }
93
+ #
94
+ # @param [#include?] allowed keys to include.
95
+ #
96
+ # @return [Hash] a copy with only the selected keys.
80
97
  def only(*allowed)
81
98
  dup.only!(*allowed)
82
99
  end
83
100
 
84
- # Create a hash with *only* key/value pairs in receiver and +allowed+
101
+ # Retain only the given keys; return self
85
102
  #
86
103
  # @example Limit a set of parameters to everything but a few known toggles:
87
- # { :one => 1, :two => 2, :three => 3 }.only(:one) #=> { :one => 1 }
88
- #
89
- # @param [Array[String, Symbol]] allowed The hash keys to include.
104
+ # { :one => 1, :two => 2, :three => 3 }.only!(:one) #=> { :one => 1 }
90
105
  #
91
- # @return [Hash] A new hash with only the selected keys.
106
+ # @param [#include?] allowed keys to include.
92
107
  #
93
- # @api public
108
+ # @return self
94
109
  def only!(*allowed)
95
- allowed = allowed.to_set
96
- select!{|key, val| allowed.include?(key) }
110
+ allowed.map!{|key| convert_key(key) } if respond_to?(:convert_key, true)
111
+ keep_if{|key, val| allowed.include?(key) }
97
112
  end
98
113
 
99
114
  end
@@ -11,13 +11,15 @@ require 'gorillib/exception/raisers'
11
11
  require 'gorillib/metaprogramming/concern'
12
12
  require 'gorillib/metaprogramming/class_attribute'
13
13
  #
14
- require 'gorillib/collection'
15
- require 'gorillib/type/extended'
16
- require 'gorillib/model/factories'
14
+ require 'gorillib/factories'
15
+ # require 'gorillib/type/extended'
17
16
  require 'gorillib/model/named_schema'
18
17
  require 'gorillib/model/validate'
19
18
  require 'gorillib/model/errors'
20
19
  #
21
20
  require 'gorillib/model/base'
21
+ require 'gorillib/model/schema_magic'
22
22
  require 'gorillib/model/field'
23
23
  require 'gorillib/model/defaults'
24
+ #
25
+ require 'gorillib/collection'
@@ -19,19 +19,14 @@ module Gorillib
19
19
  extend Gorillib::Concern
20
20
 
21
21
  def initialize(*args, &block)
22
- attrs = args.extract_options!
23
- if args.present?
24
- fns = self.class.field_names
25
- ArgumentError.check_arity!(args, 0..fns.length)
26
- attrs = attrs.merge(Hash[ fns[0..(args.length-1)].zip(args) ])
27
- end
22
+ attrs = self.class.attrs_hash_from_args(args)
28
23
  receive!(attrs, &block)
29
24
  end
30
25
 
31
26
  # Returns a Hash of all attributes
32
27
  #
33
28
  # @example Get attributes
34
- # person.attributes # => { :name => "Ben Poweski" }
29
+ # person.attributes # => { :name => "Emmet Brown", :title => "Dr" }
35
30
  #
36
31
  # @return [{Symbol => Object}] The Hash of all attributes
37
32
  def attributes
@@ -69,12 +64,12 @@ module Gorillib
69
64
  # or some such. Use `#update_attributes` if your data is already type safe.
70
65
  #
71
66
  # @param [{Symbol => Object}] hsh The values to receive
72
- # @return [Gorillib::Model] the object itself
67
+ # @return [nil] nothing
73
68
  def receive!(hsh={})
74
69
  if hsh.respond_to?(:attributes)
75
- hsh = hsh.attributes
70
+ hsh = hsh.compact_attributes
76
71
  else
77
- Gorillib::Model::Validate.hashlike!(hsh){ "attributes hash for #{self.inspect}" }
72
+ Gorillib::Model::Validate.hashlike!(hsh){ "attributes for #{self.inspect}" }
78
73
  hsh = hsh.dup
79
74
  end
80
75
  self.class.field_names.each do |field_name|
@@ -84,12 +79,12 @@ module Gorillib
84
79
  self.send("receive_#{field_name}", val)
85
80
  end
86
81
  handle_extra_attributes(hsh)
87
- self
82
+ nil
88
83
  end
89
84
 
90
85
  def handle_extra_attributes(attrs)
91
- @extra_attributes ||= Hash.new
92
- @extra_attributes.merge!(attrs)
86
+ @_extra_attributes ||= Hash.new
87
+ @_extra_attributes.merge!(attrs)
93
88
  end
94
89
 
95
90
  #
@@ -102,7 +97,7 @@ module Gorillib
102
97
  # @return [Gorillib::Model] the object itself
103
98
  def update_attributes(hsh)
104
99
  if hsh.respond_to?(:attributes) then hsh = hsh.attributes ; end
105
- Gorillib::Model::Validate.hashlike!(hsh){ "attributes hash for #{self.inspect}" }
100
+ Gorillib::Model::Validate.hashlike!(hsh){ "attributes for #{self.inspect}" }
106
101
  self.class.field_names.each do |field_name|
107
102
  if hsh.has_key?(field_name) then val = hsh[field_name]
108
103
  elsif hsh.has_key?(field_name.to_s) then val = hsh[field_name.to_s]
@@ -193,24 +188,27 @@ module Gorillib
193
188
  attributes == other.attributes
194
189
  end
195
190
 
196
- # override inspect_helper (not this) in your descendant class
191
+ # override to_inspectable (not this) in your descendant class
197
192
  # @return [String] Human-readable presentation of the attributes
198
- def inspect(detailed=true)
199
- inspect_helper(detailed, compact_attributes)
193
+ def inspect
194
+ str = '#<' << self.class.name.to_s
195
+ attrs = to_inspectable
196
+ if attrs.present?
197
+ str << '(' << attrs.map{|attr, val| "#{attr}=#{val.respond_to?(:inspect_compact) ? val.inspect_compact : val.inspect}" }.join(", ") << ')'
198
+ end
199
+ str << '>'
200
+ end
201
+
202
+ def inspect_compact
203
+ str = "#<#{self.class.name.to_s}>"
200
204
  end
201
205
 
202
206
  # assembles just the given attributes into the inspect string.
203
207
  # @return [String] Human-readable presentation of the attributes
204
- def inspect_helper(detailed, attrs)
205
- str = "#<" << self.class.name.to_s
206
- if detailed && attrs.present?
207
- str << " " << attrs.map do |attr, val|
208
- "#{attr}=#{val.is_a?(Gorillib::Model) || val.is_a?(Gorillib::GenericCollection) ? val.inspect(false) : val.inspect}"
209
- end.join(", ")
210
- end
211
- str << ">"
208
+ def to_inspectable
209
+ compact_attributes
212
210
  end
213
- private :inspect_helper
211
+ private :to_inspectable
214
212
 
215
213
  protected
216
214
 
@@ -229,7 +227,7 @@ module Gorillib
229
227
  # @return [Gorillib::Model] the new object
230
228
  def receive(attrs={}, &block)
231
229
  return nil if attrs.nil?
232
- return attrs if attrs.is_a?(self)
230
+ return attrs if native?(attrs)
233
231
  #
234
232
  Gorillib::Model::Validate.hashlike!(attrs){ "attributes for #{self.inspect}" }
235
233
  klass = attrs.has_key?(:_type) ? Gorillib::Factory(attrs[:_type]) : self
@@ -238,45 +236,13 @@ module Gorillib
238
236
  klass.new(attrs, &block)
239
237
  end
240
238
 
241
- # Defines a new field
242
- #
243
- # For each field that is defined, a getter and setter will be added as
244
- # an instance method to the model. An Field instance will be added to
245
- # result of the fields class method.
239
+ # A `native` object does not need any transformation; it is accepted directly.
240
+ # By default, an object is native if it `is_a?` this class
246
241
  #
247
- # @example
248
- # field :height, Integer
249
- #
250
- # @param [Symbol] field_name The field name. Must start with `[A-Za-z_]` and subsequently contain only `[A-Za-z0-9_]`
251
- # @param [Class] type The field's type (required)
252
- # @option options [String] doc Documentation string for the field (optional)
253
- # @option options [Proc, Object] default Default value, or proc that instance can evaluate to find default value
254
- #
255
- # @return Gorillib::Model::Field
256
- def field(field_name, type, options={})
257
- options = options.symbolize_keys
258
- field_type = options.delete(:field_type){ ::Gorillib::Model::Field }
259
- fld = field_type.new(field_name, type, self, options)
260
- @_own_fields[fld.name] = fld
261
- _reset_descendant_fields
262
- fld.send(:inscribe_methods, self)
263
- fld
264
- end
265
-
266
- # @return [{Symbol => Gorillib::Model::Field}]
267
- def fields
268
- return @_fields if defined?(@_fields)
269
- @_fields = ancestors.reverse.inject({}){|acc, ancestor| acc.merge!(ancestor.try(:_own_fields) || {}) }
270
- end
271
-
272
- # @return [true, false] true if the field is defined on this class
273
- def has_field?(field_name)
274
- fields.has_key?(field_name)
275
- end
276
-
277
- # @return [Array<Symbol>] The attribute names
278
- def field_names
279
- @_field_names ||= fields.keys
242
+ # @param obj [Object] the object that will be received
243
+ # @return [true, false] true if the item does not need conversion
244
+ def native?(obj)
245
+ obj.is_a?(self)
280
246
  end
281
247
 
282
248
  # @return Class name and its attributes
@@ -284,62 +250,10 @@ module Gorillib
284
250
  # @example Inspect the model's definition.
285
251
  # Person.inspect #=> Person[first_name, last_name]
286
252
  def inspect
287
- "#{self.name || 'anon'}[#{ field_names.join(", ") }]"
288
- end
289
-
290
- protected
291
-
292
- attr_reader :_own_fields
293
-
294
- # Ensure that classes inherit all their parents' fields, even if fields
295
- # are added after the child class is defined.
296
- def _reset_descendant_fields
297
- ObjectSpace.each_object(::Class) do |klass|
298
- klass.__send__(:remove_instance_variable, '@_fields') if (klass <= self) && klass.instance_variable_defined?('@_fields')
299
- klass.__send__(:remove_instance_variable, '@_field_names') if (klass <= self) && klass.instance_variable_defined?('@_field_names')
300
- end
301
- end
302
-
303
- # define the reader method `#foo` for a field named `:foo`
304
- def define_attribute_reader(field_name, field_type, visibility)
305
- define_meta_module_method(field_name, visibility) do
306
- begin
307
- read_attribute(field_name)
308
- rescue StandardError => err ; err.polish("#{self.class}.#{field_name}") rescue nil ; raise ; end
309
- end
253
+ "#{self.name || 'anon'}[#{ field_names.join(",") }]"
310
254
  end
255
+ def inspect_compact() self.name || inspect ; end
311
256
 
312
- # define the writer method `#foo=` for a field named `:foo`
313
- def define_attribute_writer(field_name, field_type, visibility)
314
- define_meta_module_method("#{field_name}=", visibility) do |val|
315
- write_attribute(field_name, val)
316
- end
317
- end
318
-
319
- # define the present method `#foo?` for a field named `:foo`
320
- def define_attribute_tester(field_name, field_type, visibility)
321
- field = fields[field_name]
322
- define_meta_module_method("#{field_name}?", visibility) do
323
- attribute_set?(field_name) || field.has_default?
324
- end
325
- end
326
-
327
- def define_attribute_receiver(field_name, field_type, visibility)
328
- define_meta_module_method("receive_#{field_name}", visibility) do |val|
329
- begin
330
- val = field_type.receive(val)
331
- write_attribute(field_name, val)
332
- self
333
- rescue StandardError => err ; err.polish("#{self.class}.#{field_name} type #{type} on #{val}") rescue nil ; raise ; end
334
- end
335
- end
336
-
337
- def inherited(base)
338
- base.instance_eval do
339
- @_own_fields ||= {}
340
- end
341
- super
342
- end
343
257
  end
344
258
 
345
259
  self.included do |base|