virtus 0.2.0 → 0.3.0

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 (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