virtus 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.pelusa.yml +7 -0
  2. data/.travis.yml +5 -3
  3. data/Changelog.md +17 -0
  4. data/Gemfile +4 -0
  5. data/README.md +35 -39
  6. data/TODO +12 -7
  7. data/config/flay.yml +1 -1
  8. data/config/flog.yml +1 -1
  9. data/lib/virtus.rb +8 -0
  10. data/lib/virtus/attribute.rb +8 -29
  11. data/lib/virtus/attribute/boolean.rb +1 -1
  12. data/lib/virtus/attribute/default_value.rb +15 -45
  13. data/lib/virtus/attribute/default_value/from_callable.rb +33 -0
  14. data/lib/virtus/attribute/default_value/from_clonable.rb +40 -0
  15. data/lib/virtus/attribute/default_value/from_symbol.rb +35 -0
  16. data/lib/virtus/attribute/embedded_value.rb +3 -14
  17. data/lib/virtus/class_methods.rb +17 -0
  18. data/lib/virtus/coercion/hash.rb +0 -11
  19. data/lib/virtus/coercion/object.rb +98 -0
  20. data/lib/virtus/coercion/string.rb +9 -2
  21. data/lib/virtus/coercion/time_coercions.rb +2 -5
  22. data/lib/virtus/instance_methods.rb +16 -37
  23. data/lib/virtus/support/type_lookup.rb +1 -2
  24. data/lib/virtus/value_object.rb +31 -8
  25. data/lib/virtus/value_object/equalizer.rb +21 -26
  26. data/lib/virtus/version.rb +1 -1
  27. data/spec/integration/custom_attributes_spec.rb +1 -1
  28. data/spec/integration/default_values_spec.rb +15 -3
  29. data/spec/integration/defining_attributes_spec.rb +1 -1
  30. data/spec/integration/mass_assignment_with_accessors_spec.rb +44 -0
  31. data/spec/integration/virtus/value_object_spec.rb +2 -2
  32. data/spec/spec_helper.rb +8 -1
  33. data/spec/unit/virtus/attribute/class_methods/determine_type_spec.rb +1 -1
  34. data/spec/unit/virtus/attribute/default_spec.rb +1 -1
  35. data/spec/unit/virtus/attribute/default_value/evaluate_spec.rb +25 -11
  36. data/spec/unit/virtus/attribute/embedded_value/class_methods/merge_options_spec.rb +1 -1
  37. data/spec/unit/virtus/attribute/embedded_value/coerce_spec.rb +1 -1
  38. data/spec/unit/virtus/class_methods/allowed_writer_methods_spec.rb +25 -0
  39. data/spec/unit/virtus/coercion/object/class_methods/to_array_spec.rb +51 -0
  40. data/spec/unit/virtus/coercion/object/class_methods/to_hash_spec.rb +22 -0
  41. data/spec/unit/virtus/coercion/object/class_methods/to_integer_spec.rb +22 -0
  42. data/spec/unit/virtus/coercion/object/class_methods/to_string_spec.rb +22 -0
  43. data/spec/unit/virtus/coercion/string/class_methods/to_constant_spec.rb +37 -1
  44. data/spec/unit/virtus/instance_methods/attributes_spec.rb +14 -2
  45. data/spec/unit/virtus/value_object/class_methods/allowed_writer_methods_spec.rb +15 -0
  46. data/spec/unit/virtus/value_object/class_methods/equalizer_spec.rb +1 -1
  47. data/spec/unit/virtus/value_object/initialize_spec.rb +1 -1
  48. data/spec/unit/virtus/value_object/with_spec.rb +1 -1
  49. metadata +17 -10
  50. data/spec/unit/virtus/attribute/default_value/instance_methods/evaluate_spec.rb +0 -30
  51. data/spec/unit/virtus/attribute/instance_variable_name_spec.rb +0 -12
  52. data/spec/unit/virtus/attribute/reader_visibility_spec.rb +0 -24
  53. data/spec/unit/virtus/attribute/writer_visibility_spec.rb +0 -24
  54. data/spec/unit/virtus/coercion/hash/class_methods/to_array_spec.rb +0 -12
@@ -0,0 +1,7 @@
1
+ sources: lib/**/*.rb
2
+
3
+ lints:
4
+ InstanceVariables:
5
+ limit: 3
6
+ LineRestriction:
7
+ limit: 124
@@ -1,15 +1,17 @@
1
+ language: ruby
1
2
  bundler_args: --without guard metrics
2
3
  script: "bundle exec rake spec"
3
4
  rvm:
4
5
  - 1.8.7
5
6
  - 1.9.2
6
7
  - 1.9.3
7
- - ruby-head
8
- - ree
9
8
  - jruby-18mode
10
9
  - jruby-19mode
11
10
  - rbx-18mode
12
- # - rbx-19mode # FIXME: uncomment when rbx 1.9 is more stable
11
+ - rbx-19mode
12
+ - ree
13
+ - ruby-head
14
+ - jruby-head
13
15
  notifications:
14
16
  email:
15
17
  - piotr.solnica@gmail.com
@@ -1,3 +1,20 @@
1
+ # v0.3.0 to-be-released
2
+
3
+ * [feature] Support for default values from a symbol (which can be a method name) (solnic)
4
+ * [feature] Support for mass-assignment via custom setters not generated with attribute (fgrehm)
5
+ * [feature] Virtus::Coercion::String.to_constant handles namespaced names (dkubb)
6
+ * [feature] New coercion: Virtus::Coercion::Object.to_array (dkubb)
7
+ * [feature] New coercion: Virtus::Coercion::Object.to_hash (dkubb)
8
+ * [feature] New coercion: Virtus::Coercion::Object.to_string (dkubb)
9
+ * [feature] New coercion: Virtus::Coercion::Object.to_integer (dkubb)
10
+ * [changed] EmbeddedValue relies on @primitive setting rather than @model (mbj)
11
+ * [BREAKING CHANGE] Removed Attribute#writer_visibility in favor of Attribute#public_writer? (solnic)
12
+ * [BREAKING CHANGE] Removed Attribute#reader_visibility in favor of Attribute#public_reader? (solnic)
13
+ * [BREAKING CHANGE] Removed Attribute#instance_variable_name - this is a private ivar (solnic)
14
+ * [BREAKING CHANGE] Removed Equalizer#host_name and Equalizer#keys (solnic)
15
+
16
+ [Compare v0.2.0..master](https://github.com/solnic/virtus/compare/v0.2.0...master)
17
+
1
18
  # v0.2.0 2012-02-08
2
19
 
3
20
  * [feature] Support for Value Objects (emmanuel)
data/Gemfile CHANGED
@@ -20,4 +20,8 @@ group :metrics do
20
20
  gem 'rcov', '~> 0.9.9'
21
21
  gem 'ruby2ruby', '= 1.2.2'
22
22
  end
23
+
24
+ platforms :rbx do
25
+ gem 'pelusa', :git => 'https://github.com/codegram/pelusa.git'
26
+ end
23
27
  end
data/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  virtus
2
2
  ======
3
3
 
4
- [![Build Status](http://travis-ci.org/solnic/virtus.png)](http://travis-ci.org/solnic/virtus)
4
+ [![Build Status](https://secure.travis-ci.org/solnic/virtus.png)](http://travis-ci.org/solnic/virtus)
5
+ [![Dependency Status](https://gemnasium.com/solnic/virtus.png)](https://gemnasium.com/solnic/virtus)
6
+
7
+ [Metrics on CodeClimate](https://codeclimate.com/github/solnic/virtus)
5
8
 
6
9
  This is a partial extraction of the DataMapper [Property
7
10
  API](http://rubydoc.info/github/datamapper/dm-core/master/DataMapper/Property)
@@ -18,11 +21,9 @@ Installation
18
21
  $ gem install virtus
19
22
  ```
20
23
 
21
- or
24
+ or in your **Gemfile**
22
25
 
23
26
  ``` ruby
24
- # ./Gemfile
25
-
26
27
  gem 'virtus'
27
28
  ```
28
29
 
@@ -33,8 +34,6 @@ Examples
33
34
 
34
35
 
35
36
  ``` ruby
36
- require 'virtus'
37
-
38
37
  class User
39
38
  include Virtus
40
39
 
@@ -43,41 +42,44 @@ class User
43
42
  attribute :birthday, DateTime
44
43
  end
45
44
 
46
- user = User.new :name => 'Piotr', :age => 28
47
- user.attributes
48
- # => { :name => "Piotr", :age => 28 }
45
+ user = User.new(:name => 'Piotr', :age => 28)
46
+ user.attributes # => { :name => "Piotr", :age => 28 }
49
47
 
50
- user.name
51
- # => "Piotr"
48
+ user.name # => "Piotr"
52
49
 
53
- user.age = '28'
54
- # => 28
55
- user.age.class
56
- # => Fixnum
50
+ user.age = '28' # => 28
51
+ user.age.class # => Fixnum
57
52
 
58
- user.birthday = 'November 18th, 1983'
59
- # => #<DateTime: 1983-11-18T00:00:00+00:00 (4891313/2,0/1,2299161)>
53
+ user.birthday = 'November 18th, 1983' # => #<DateTime: 1983-11-18T00:00:00+00:00 (4891313/2,0/1,2299161)>
60
54
  ```
61
55
 
62
56
 
63
57
  **Default values**
64
58
 
65
59
  ``` ruby
66
- require 'virtus'
67
-
68
60
  class Page
69
61
  include Virtus
70
62
 
71
63
  attribute :title, String
64
+
65
+ # default from a singleton value (integer in this case)
72
66
  attribute :views, Integer, :default => 0
67
+
68
+ # default from a callable object (proc in this case)
73
69
  attribute :slug, String, :default => lambda { |page, attribute| page.title.downcase.gsub(' ', '-') }
70
+
71
+ # default from a method name as symbol
72
+ attribute :editor_title, String, :default => :default_editor_title
73
+
74
+ def default_editor_title
75
+ published? ? title : "UNPUBLISHED: #{title}"
76
+ end
74
77
  end
75
78
 
76
- page = Page.new :title => 'Virtus Is Awesome'
77
- page.slug
78
- # => 'virtus-is-awesome'
79
- page.views
80
- # => 0
79
+ page = Page.new(:title => 'Virtus Is Awesome', :editor_title => 'Virtus README')
80
+ page.slug # => 'virtus-is-awesome'
81
+ page.views # => 0
82
+ page.editor_title # => "UNPUBSLISHED: Virtus README"
81
83
  ```
82
84
 
83
85
  **Embedded Value**
@@ -115,7 +117,6 @@ user.address.city.name # => "NYC"
115
117
 
116
118
  ``` ruby
117
119
  # Support "primitive" classes
118
-
119
120
  class Book
120
121
  include Virtus
121
122
 
@@ -181,7 +182,7 @@ venue = Venue.new(
181
182
  :name => 'Pub',
182
183
  :location => { :latitude => 37.160317, :longitude => -98.437500 })
183
184
 
184
- venue.location.latitude # => 37.160317
185
+ venue.location.latitude # => 37.160317
185
186
  venue.location.longitude # => -98.4375
186
187
 
187
188
  # Supports object's equality
@@ -200,7 +201,6 @@ It's super easy to add your own coercion classes.
200
201
  Take a look:
201
202
 
202
203
  ``` ruby
203
- require 'virtus'
204
204
  require 'digest/md5'
205
205
 
206
206
  # Our new attribute type
@@ -228,17 +228,14 @@ class User
228
228
  attribute :password, MD5
229
229
  end
230
230
 
231
- user = User.new :name => 'Piotr', :password => 'foobar'
232
- user.name
233
- # => 'Piotr'
234
- user.password
235
- # => '3858f62230ac3c915f300c664312c63f'
231
+ user = User.new(:name => 'Piotr', :password => 'foobar')
232
+ user.name # => 'Piotr'
233
+ user.password # => '3858f62230ac3c915f300c664312c63f'
236
234
  ```
237
235
 
238
236
  **Custom Attributes**
239
237
 
240
238
  ``` ruby
241
- require 'virtus'
242
239
  require 'json'
243
240
 
244
241
  module MyAppClass
@@ -262,10 +259,8 @@ module MyAppClass
262
259
  end
263
260
 
264
261
  user = MyApp::User.new
265
- user.info = '{"email":"john@domain.com"}'
266
- # => {"email"=>"john@domain.com"}
267
- user.info.class
268
- # => Hash
262
+ user.info = '{"email":"john@domain.com"}' # => {"email"=>"john@domain.com"}
263
+ user.info.class # => Hash
269
264
  ```
270
265
 
271
266
 
@@ -275,10 +270,11 @@ Credits
275
270
  * Dan Kubb ([dkubb](https://github.com/dkubb))
276
271
  * Chris Corbyn ([d11wtq](https://github.com/d11wtq))
277
272
  * Emmanuel Gomez ([emmanuel](https://github.com/emmanuel))
273
+ * Fabio Rehm ([fgrehm](https://github.com/fgrehm))
278
274
  * Ryan Closner ([rclosner](https://github.com/rclosner))
275
+ * Markus Schirp ([mbj](https://github.com/mbj))
279
276
  * Yves Senn ([senny](https://github.com/senny))
280
277
 
281
-
282
278
  Contributing
283
279
  -------------
284
280
 
@@ -286,7 +282,7 @@ Contributing
286
282
  * Make your feature addition or bug fix.
287
283
  * Add tests for it. This is important so I don't break it in a
288
284
  future version unintentionally.
289
- * Commit, do not mess with rakefile, version, or history.
285
+ * Commit, do not mess with Rakefile or version
290
286
  (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
291
287
  * Send me a pull request. Bonus points for topic branches.
292
288
 
data/TODO CHANGED
@@ -1,31 +1,36 @@
1
1
  * Add missing specs:
2
2
  * Add spec file spec/unit/virtus/attribute/collection/member_coercion/coerce_and_append_member_spec.rb for Virtus::Attribute::Collection::MemberCoercion#coerce_and_append_member
3
- * Add spec file spec/unit/virtus/attribute/collection/coerce_and_append_member_spec.rb for Virtus::Attribute::Collection#coerce_and_append_member
4
3
  * Add spec file spec/unit/virtus/attribute/collection/member_type_spec.rb for Virtus::Attribute::Collection#member_type
5
4
  * Add spec file spec/unit/virtus/attribute/collection/new_collection_spec.rb for Virtus::Attribute::Collection#new_collection
5
+ * Add spec file spec/unit/virtus/attribute/collection/coerce_and_append_member_spec.rb for Virtus::Attribute::Collection#coerce_and_append_member
6
+ * Add spec file spec/unit/virtus/attribute/default_value/from_symbol/class_methods/handle_spec.rb for Virtus::Attribute::DefaultValue::FromSymbol.handle?
7
+ * Add spec file spec/unit/virtus/attribute/default_value/from_symbol/evaluate_spec.rb for Virtus::Attribute::DefaultValue::FromSymbol#evaluate
8
+ * Add spec file spec/unit/virtus/attribute/default_value/from_callable/class_methods/handle_spec.rb for Virtus::Attribute::DefaultValue::FromCallable.handle?
9
+ * Add spec file spec/unit/virtus/attribute/default_value/from_callable/evaluate_spec.rb for Virtus::Attribute::DefaultValue::FromCallable#evaluate
10
+ * Add spec file spec/unit/virtus/attribute/default_value/from_clonable/class_methods/handle_spec.rb for Virtus::Attribute::DefaultValue::FromClonable.handle?
11
+ * Add spec file spec/unit/virtus/attribute/default_value/from_clonable/evaluate_spec.rb for Virtus::Attribute::DefaultValue::FromClonable#evaluate
12
+ * Add spec file spec/unit/virtus/attribute/default_value/class_methods/build_spec.rb for Virtus::Attribute::DefaultValue.build
6
13
  * Add spec file spec/unit/virtus/coercion/string/class_methods/to_symbol_spec.rb for Virtus::Coercion::String.to_symbol
7
14
  * Add spec file spec/unit/virtus/coercion/time/class_methods/to_integer_spec.rb for Virtus::Coercion::Time.to_integer
8
- * Add spec file spec/unit/virtus/coercion/time_coercions/to_time_spec.rb for Virtus::Coercion::TimeCoercions#to_time
9
15
  * Add spec file spec/unit/virtus/coercion/time_coercions/to_datetime_spec.rb for Virtus::Coercion::TimeCoercions#to_datetime
16
+ * Add spec file spec/unit/virtus/coercion/time_coercions/to_time_spec.rb for Virtus::Coercion::TimeCoercions#to_time
10
17
  * Add spec file spec/unit/virtus/coercion/time_coercions/to_date_spec.rb for Virtus::Coercion::TimeCoercions#to_date
11
18
  * Add spec file spec/unit/virtus/coercion/time_coercions/to_string_spec.rb for Virtus::Coercion::TimeCoercions#to_string
12
19
  * Add spec file spec/unit/virtus/coercion/array/class_methods/to_set_spec.rb for Virtus::Coercion::Array.to_set
13
20
  * Add spec file spec/unit/virtus/coercion/decimal/class_methods/to_decimal_spec.rb for Virtus::Coercion::Decimal.to_decimal
14
21
  * Add spec file spec/unit/virtus/coercion/float/class_methods/to_float_spec.rb for Virtus::Coercion::Float.to_float
15
22
  * Add spec file spec/unit/virtus/coercion/integer/class_methods/to_integer_spec.rb for Virtus::Coercion::Integer.to_integer
23
+ * Add spec file spec/unit/virtus/coercion/numeric/class_methods/to_decimal_spec.rb for Virtus::Coercion::Numeric.to_decimal
16
24
  * Add spec file spec/unit/virtus/coercion/numeric/class_methods/to_float_spec.rb for Virtus::Coercion::Numeric.to_float
17
25
  * Add spec file spec/unit/virtus/coercion/numeric/class_methods/to_integer_spec.rb for Virtus::Coercion::Numeric.to_integer
18
26
  * Add spec file spec/unit/virtus/coercion/numeric/class_methods/to_string_spec.rb for Virtus::Coercion::Numeric.to_string
19
- * Add spec file spec/unit/virtus/coercion/numeric/class_methods/to_decimal_spec.rb for Virtus::Coercion::Numeric.to_decimal
20
27
  * Add spec file spec/unit/virtus/coercion/class_methods/element_reference_spec.rb for Virtus::Coercion.[]
21
28
  * Add spec file spec/unit/virtus/coercion/class_methods/primitive_spec.rb for Virtus::Coercion.primitive
22
29
  * Add spec file spec/unit/virtus/value_object/class_methods/attribute_spec.rb for Virtus::ValueObject::ClassMethods#attribute
23
30
  * Add spec file spec/unit/virtus/value_object/instance_methods/with_spec.rb for Virtus::ValueObject::InstanceMethods#with
24
- * Add spec file spec/unit/virtus/value_object/equalizer/compile_spec.rb for Virtus::ValueObject::Equalizer#compile
25
31
  * Add spec file spec/unit/virtus/value_object/equalizer/append_spec.rb for Virtus::ValueObject::Equalizer#<<
26
- * Add spec file spec/unit/virtus/value_object/equalizer/host_name_spec.rb for Virtus::ValueObject::Equalizer#host_name
27
- * Add spec file spec/unit/virtus/value_object/equalizer/keys_spec.rb for Virtus::ValueObject::Equalizer#keys
28
- * Add spec file spec/unit/virtus/attributes_accessor/define_writer_method_spec.rb for Virtus::AttributesAccessor#define_writer_method
32
+ * Add spec file spec/unit/virtus/value_object/equalizer/compile_spec.rb for Virtus::ValueObject::Equalizer#compile
29
33
  * Add spec file spec/unit/virtus/attributes_accessor/define_reader_method_spec.rb for Virtus::AttributesAccessor#define_reader_method
34
+ * Add spec file spec/unit/virtus/attributes_accessor/define_writer_method_spec.rb for Virtus::AttributesAccessor#define_writer_method
30
35
 
31
36
  * Make #to_time #to_date and #to_datetime work on Ruby 1.8.7 instead of typecasting to string and parsing the value
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 19
3
- total_score: 354
3
+ total_score: 326
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 16.8
2
+ threshold: 19.4
@@ -7,6 +7,10 @@ require 'bigdecimal/util'
7
7
  # Base module which adds Attribute API to your classes
8
8
  module Virtus
9
9
 
10
+ # Provides args for const_get and const_defined? to make them behave
11
+ # consistently across different versions of ruby
12
+ EXTRA_CONST_ARGS = (RUBY_VERSION < '1.9' || RUBY_ENGINE == 'rbx' ? [] : [ false ]).freeze
13
+
10
14
  # Represents an undefined parameter used by auto-generated option methods
11
15
  Undefined = Object.new.freeze
12
16
 
@@ -57,6 +61,10 @@ require 'virtus/coercion/string'
57
61
  require 'virtus/coercion/symbol'
58
62
 
59
63
  require 'virtus/attribute/default_value'
64
+ require 'virtus/attribute/default_value/from_clonable'
65
+ require 'virtus/attribute/default_value/from_callable'
66
+ require 'virtus/attribute/default_value/from_symbol'
67
+
60
68
  require 'virtus/attribute'
61
69
  require 'virtus/attribute/object'
62
70
  require 'virtus/attribute/class'
@@ -30,27 +30,6 @@ module Virtus
30
30
  # @api private
31
31
  attr_reader :options
32
32
 
33
- # Returns instance variable name of the attribute
34
- #
35
- # @return [Symbol]
36
- #
37
- # @api private
38
- attr_reader :instance_variable_name
39
-
40
- # Returns reader visibility
41
- #
42
- # @return [Symbol]
43
- #
44
- # @api private
45
- attr_reader :reader_visibility
46
-
47
- # Returns write visibility
48
- #
49
- # @return [Symbol]
50
- #
51
- # @api private
52
- attr_reader :writer_visibility
53
-
54
33
  # Returns method name that should be used for coerceing
55
34
  #
56
35
  # @return [Symbol]
@@ -148,7 +127,7 @@ module Virtus
148
127
  @instance_variable_name = "@#{@name}".to_sym
149
128
  @primitive = @options.fetch(:primitive)
150
129
  @coercion_method = @options.fetch(:coercion_method)
151
- @default = DefaultValue.new(self, @options[:default])
130
+ @default = DefaultValue.build(self, @options[:default])
152
131
  initialize_visibility
153
132
  end
154
133
 
@@ -178,7 +157,7 @@ module Virtus
178
157
  #
179
158
  # @api public
180
159
  def get(instance)
181
- if instance.instance_variable_defined?(instance_variable_name)
160
+ if instance.instance_variable_defined?(@instance_variable_name)
182
161
  get!(instance)
183
162
  else
184
163
  value = default.evaluate(instance)
@@ -197,7 +176,7 @@ module Virtus
197
176
  #
198
177
  # @api public
199
178
  def get!(instance)
200
- instance.instance_variable_get(instance_variable_name)
179
+ instance.instance_variable_get(@instance_variable_name)
201
180
  end
202
181
 
203
182
  # Sets the value on the instance
@@ -221,7 +200,7 @@ module Virtus
221
200
  #
222
201
  # @api public
223
202
  def set!(instance, value)
224
- instance.instance_variable_set(instance_variable_name, value)
203
+ instance.instance_variable_set(@instance_variable_name, value)
225
204
  self
226
205
  end
227
206
 
@@ -282,7 +261,7 @@ module Virtus
282
261
  #
283
262
  # @api private
284
263
  def define_reader_method(mod)
285
- mod.define_reader_method(self, name, reader_visibility)
264
+ mod.define_reader_method(self, name, @reader_visibility)
286
265
  self
287
266
  end
288
267
 
@@ -294,7 +273,7 @@ module Virtus
294
273
  #
295
274
  # @api private
296
275
  def define_writer_method(mod)
297
- mod.define_writer_method(self, "#{name}=".to_sym, writer_visibility)
276
+ mod.define_writer_method(self, "#{name}=".to_sym, @writer_visibility)
298
277
  self
299
278
  end
300
279
 
@@ -304,7 +283,7 @@ module Virtus
304
283
  #
305
284
  # @api private
306
285
  def public_reader?
307
- reader_visibility == :public
286
+ @reader_visibility == :public
308
287
  end
309
288
 
310
289
  # Returns a Boolean indicating whether the writer method is public
@@ -313,7 +292,7 @@ module Virtus
313
292
  #
314
293
  # @api private
315
294
  def public_writer?
316
- writer_visibility == :public
295
+ @writer_visibility == :public
317
296
  end
318
297
 
319
298
  private
@@ -43,7 +43,7 @@ module Virtus
43
43
  # @api private
44
44
  def define_reader_method(mod)
45
45
  super
46
- mod.define_reader_method(self, "#{name}?", reader_visibility)
46
+ mod.define_reader_method(self, "#{name}?", @reader_visibility)
47
47
  self
48
48
  end
49
49
 
@@ -2,9 +2,20 @@ module Virtus
2
2
  class Attribute
3
3
 
4
4
  # Class representing the default value option
5
+ #
6
+ # @api private
5
7
  class DefaultValue
6
- SINGLETON_CLASSES = [ ::NilClass, ::TrueClass, ::FalseClass,
7
- ::Numeric, ::Symbol ].freeze
8
+ extend DescendantsTracker
9
+
10
+ # Builds a default value instance
11
+ #
12
+ # @return [Virtus::Attribute::DefaultValue]
13
+ #
14
+ # @api private
15
+ def self.build(*args)
16
+ klass = descendants.detect { |descendant| descendant.handle?(*args) } || self
17
+ klass.new(*args)
18
+ end
8
19
 
9
20
  # Returns the attribute associated with this default value instance
10
21
  #
@@ -40,50 +51,9 @@ module Virtus
40
51
  #
41
52
  # @api private
42
53
  def evaluate(instance)
43
- if callable?
44
- call(instance)
45
- elsif cloneable?
46
- value.clone
47
- else
48
- value
49
- end
50
- end
51
-
52
- private
53
-
54
- # Evaluates a proc value
55
- #
56
- # @param [Object]
57
- #
58
- # @return [Object] evaluated value
59
- #
60
- # @api private
61
- def call(instance)
62
- value.call(instance, attribute)
54
+ value
63
55
  end
64
-
65
- # Returns if the value is callable
66
- #
67
- # @return [TrueClass,FalseClass]
68
- #
69
- # @api private
70
- def callable?
71
- value.respond_to?(:call)
72
- end
73
-
74
- # Returns whether or not the value is cloneable
75
- #
76
- # # return [TrueClass, FalseClass]
77
- #
78
- # @api private
79
- def cloneable?
80
- case value
81
- when *SINGLETON_CLASSES then false
82
- else
83
- true
84
- end
85
- end
86
-
87
56
  end # class DefaultValue
57
+
88
58
  end # class Attribute
89
59
  end # module Virtus