gorillib 0.4.1pre → 0.4.2pre

Sign up to get free protection for your applications and to get access to all the features.
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|