virtus 0.0.2 → 0.0.3

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 (85) hide show
  1. data/.gitignore +3 -0
  2. data/.rvmrc +1 -1
  3. data/Gemfile +20 -1
  4. data/History.txt +21 -0
  5. data/README.markdown +2 -2
  6. data/Rakefile +1 -2
  7. data/VERSION +1 -1
  8. data/config/flay.yml +3 -0
  9. data/config/flog.yml +2 -0
  10. data/config/roodi.yml +18 -0
  11. data/config/site.reek +91 -0
  12. data/config/yardstick.yml +2 -0
  13. data/lib/virtus.rb +51 -45
  14. data/lib/virtus/attribute.rb +301 -0
  15. data/lib/virtus/attribute/array.rb +17 -0
  16. data/lib/virtus/attribute/boolean.rb +60 -0
  17. data/lib/virtus/attribute/date.rb +35 -0
  18. data/lib/virtus/attribute/date_time.rb +34 -0
  19. data/lib/virtus/attribute/decimal.rb +24 -0
  20. data/lib/virtus/attribute/float.rb +33 -0
  21. data/lib/virtus/attribute/hash.rb +18 -0
  22. data/lib/virtus/attribute/integer.rb +30 -0
  23. data/lib/virtus/{attributes → attribute}/numeric.rb +2 -3
  24. data/lib/virtus/{attributes → attribute}/object.rb +2 -1
  25. data/lib/virtus/attribute/string.rb +31 -0
  26. data/lib/virtus/attribute/time.rb +34 -0
  27. data/lib/virtus/class_methods.rb +25 -8
  28. data/lib/virtus/instance_methods.rb +48 -9
  29. data/lib/virtus/support/chainable.rb +4 -6
  30. data/lib/virtus/typecast/boolean.rb +27 -0
  31. data/lib/virtus/typecast/numeric.rb +82 -0
  32. data/lib/virtus/typecast/time.rb +162 -0
  33. data/spec/integration/virtus/attributes/attribute/typecast_spec.rb +4 -4
  34. data/spec/integration/virtus/class_methods/attribute_spec.rb +1 -1
  35. data/spec/integration/virtus/class_methods/attributes_spec.rb +3 -2
  36. data/spec/integration/virtus/class_methods/const_missing_spec.rb +2 -2
  37. data/spec/rcov.opts +6 -0
  38. data/spec/spec_helper.rb +0 -9
  39. data/spec/unit/shared/attribute.rb +8 -8
  40. data/spec/unit/virtus/{attributes → attribute}/array_spec.rb +1 -1
  41. data/spec/unit/virtus/attribute/attribute_spec.rb +12 -0
  42. data/spec/unit/virtus/{attributes → attribute}/boolean_spec.rb +4 -4
  43. data/spec/unit/virtus/{attributes → attribute}/date_spec.rb +13 -7
  44. data/spec/unit/virtus/{attributes → attribute}/date_time_spec.rb +31 -10
  45. data/spec/unit/virtus/{attributes → attribute}/decimal_spec.rb +18 -18
  46. data/spec/unit/virtus/{attributes → attribute}/float_spec.rb +18 -18
  47. data/spec/unit/virtus/{attributes → attribute}/hash_spec.rb +1 -1
  48. data/spec/unit/virtus/{attributes → attribute}/integer_spec.rb +18 -18
  49. data/spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb +15 -0
  50. data/spec/unit/virtus/attribute/object/class_methods/descendants_spec.rb +16 -0
  51. data/spec/unit/virtus/{attributes → attribute}/string_spec.rb +2 -2
  52. data/spec/unit/virtus/{attributes → attribute}/time_spec.rb +19 -9
  53. data/spec/unit/virtus/class_methods/new_spec.rb +7 -7
  54. data/spec/unit/virtus/determine_type_spec.rb +4 -4
  55. data/spec/unit/virtus/instance_methods/attribute_get_spec.rb +1 -1
  56. data/spec/unit/virtus/instance_methods/attribute_set_spec.rb +2 -2
  57. data/spec/unit/virtus/instance_methods/attributes_spec.rb +2 -2
  58. data/tasks/metrics/ci.rake +7 -0
  59. data/tasks/metrics/flay.rake +41 -0
  60. data/tasks/metrics/flog.rake +43 -0
  61. data/tasks/metrics/heckle.rake +261 -0
  62. data/tasks/metrics/metric_fu.rake +29 -0
  63. data/tasks/metrics/reek.rake +9 -0
  64. data/tasks/metrics/roodi.rake +15 -0
  65. data/tasks/metrics/yardstick.rake +23 -0
  66. data/tasks/spec.rake +26 -0
  67. data/tasks/yard.rake +9 -0
  68. data/virtus.gemspec +48 -33
  69. metadata +51 -41
  70. data/lib/virtus/attributes/array.rb +0 -8
  71. data/lib/virtus/attributes/attribute.rb +0 -214
  72. data/lib/virtus/attributes/boolean.rb +0 -39
  73. data/lib/virtus/attributes/date.rb +0 -44
  74. data/lib/virtus/attributes/date_time.rb +0 -43
  75. data/lib/virtus/attributes/decimal.rb +0 -24
  76. data/lib/virtus/attributes/float.rb +0 -20
  77. data/lib/virtus/attributes/hash.rb +0 -8
  78. data/lib/virtus/attributes/integer.rb +0 -20
  79. data/lib/virtus/attributes/string.rb +0 -11
  80. data/lib/virtus/attributes/time.rb +0 -45
  81. data/lib/virtus/attributes/typecast/numeric.rb +0 -32
  82. data/lib/virtus/attributes/typecast/time.rb +0 -27
  83. data/spec/unit/virtus/attributes/attribute_spec.rb +0 -13
  84. data/spec/unit/virtus/attributes/numeric/class_methods/descendants_spec.rb +0 -15
  85. data/spec/unit/virtus/attributes/object/class_methods/descendants_spec.rb +0 -16
@@ -0,0 +1,29 @@
1
+ begin
2
+ require 'metric_fu'
3
+ require 'json'
4
+
5
+ # XXX: temporary hack until metric_fu is fixed
6
+ MetricFu::Saikuro.class_eval { include FileUtils }
7
+
8
+ MetricFu::Configuration.run do |config|
9
+ config.rcov = {
10
+ :environment => 'test',
11
+ :test_files => %w[ spec/**/*_spec.rb ],
12
+ :rcov_opts => %w[
13
+ --sort coverage
14
+ --no-html
15
+ --text-coverage
16
+ --no-color
17
+ --profile
18
+ --exclude spec/,^/
19
+ --include lib:spec
20
+ ],
21
+ }
22
+ end
23
+ rescue LoadError
24
+ namespace :metrics do
25
+ task :all do
26
+ abort 'metric_fu is not available. In order to run metrics:all, you must: gem install metric_fu'
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ begin
2
+ require 'reek/rake/task'
3
+
4
+ Reek::Rake::Task.new
5
+ rescue LoadError
6
+ task :reek do
7
+ abort "Reek is not available. In order to run reek, you must: gem install reek"
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ begin
2
+ require 'roodi'
3
+ require 'rake/tasklib'
4
+ require 'roodi_task'
5
+
6
+ RoodiTask.new do |t|
7
+ t.verbose = false
8
+ t.config = File.expand_path('../../../config/roodi.yml', __FILE__)
9
+ t.patterns = %w[ lib/**/*.rb ]
10
+ end
11
+ rescue LoadError
12
+ task :roodi do
13
+ abort 'Roodi is not available. In order to run roodi, you must: gem install roodi'
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ begin
2
+ require 'pathname'
3
+ require 'yardstick'
4
+ require 'yardstick/rake/measurement'
5
+ require 'yardstick/rake/verify'
6
+ require 'yaml'
7
+
8
+ config = YAML.load_file(File.expand_path('../../../config/yardstick.yml', __FILE__))
9
+
10
+ # yardstick_measure task
11
+ Yardstick::Rake::Measurement.new
12
+
13
+ # verify_measurements task
14
+ Yardstick::Rake::Verify.new do |verify|
15
+ verify.threshold = config.fetch('threshold')
16
+ end
17
+ rescue LoadError
18
+ %w[ yardstick_measure verify_measurements ].each do |name|
19
+ task name.to_s do
20
+ abort "Yardstick is not available. In order to run #{name}, you must: gem install yardstick"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ rescue LoadError
6
+ task :spec do
7
+ abort 'rspec is not available. In order to run spec, you must: gem install rspec'
8
+ end
9
+ end
10
+
11
+ begin
12
+ desc "Generate code coverage"
13
+ RSpec::Core::RakeTask.new(:rcov) do |t|
14
+ t.rcov = true
15
+ t.rcov_opts = File.read('spec/rcov.opts').split(/\s+/)
16
+ end
17
+ rescue LoadError
18
+ %w[ rcov verify_rcov ].each do |name|
19
+ task name do
20
+ abort "rcov is not available. In order to run #{name}, you must: gem install rcov"
21
+ end
22
+ end
23
+ end
24
+
25
+ task :test => :spec
26
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ begin
2
+ require 'yard'
3
+
4
+ YARD::Rake::YardocTask.new
5
+ rescue LoadError
6
+ task :yard do
7
+ abort 'YARD is not available. In order to run yard, you must: gem install yard'
8
+ end
9
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{virtus}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = [%q{Piotr Solnica}]
12
- s.date = %q{2011-06-06}
12
+ s.date = %q{2011-06-09}
13
13
  s.description = %q{Attributes for your plain ruby objects}
14
14
  s.email = [%q{piotr@rubyverse.com}]
15
15
  s.extra_rdoc_files = [
@@ -21,53 +21,71 @@ Gem::Specification.new do |s|
21
21
  ".rvmrc",
22
22
  ".travis.yml",
23
23
  "Gemfile",
24
+ "History.txt",
24
25
  "LICENSE",
25
26
  "README.markdown",
26
27
  "Rakefile",
27
28
  "VERSION",
29
+ "config/flay.yml",
30
+ "config/flog.yml",
31
+ "config/roodi.yml",
32
+ "config/site.reek",
33
+ "config/yardstick.yml",
28
34
  "lib/virtus.rb",
29
- "lib/virtus/attributes/array.rb",
30
- "lib/virtus/attributes/attribute.rb",
31
- "lib/virtus/attributes/boolean.rb",
32
- "lib/virtus/attributes/date.rb",
33
- "lib/virtus/attributes/date_time.rb",
34
- "lib/virtus/attributes/decimal.rb",
35
- "lib/virtus/attributes/float.rb",
36
- "lib/virtus/attributes/hash.rb",
37
- "lib/virtus/attributes/integer.rb",
38
- "lib/virtus/attributes/numeric.rb",
39
- "lib/virtus/attributes/object.rb",
40
- "lib/virtus/attributes/string.rb",
41
- "lib/virtus/attributes/time.rb",
42
- "lib/virtus/attributes/typecast/numeric.rb",
43
- "lib/virtus/attributes/typecast/time.rb",
35
+ "lib/virtus/attribute.rb",
36
+ "lib/virtus/attribute/array.rb",
37
+ "lib/virtus/attribute/boolean.rb",
38
+ "lib/virtus/attribute/date.rb",
39
+ "lib/virtus/attribute/date_time.rb",
40
+ "lib/virtus/attribute/decimal.rb",
41
+ "lib/virtus/attribute/float.rb",
42
+ "lib/virtus/attribute/hash.rb",
43
+ "lib/virtus/attribute/integer.rb",
44
+ "lib/virtus/attribute/numeric.rb",
45
+ "lib/virtus/attribute/object.rb",
46
+ "lib/virtus/attribute/string.rb",
47
+ "lib/virtus/attribute/time.rb",
44
48
  "lib/virtus/class_methods.rb",
45
49
  "lib/virtus/instance_methods.rb",
46
50
  "lib/virtus/support/chainable.rb",
51
+ "lib/virtus/typecast/boolean.rb",
52
+ "lib/virtus/typecast/numeric.rb",
53
+ "lib/virtus/typecast/time.rb",
47
54
  "spec/integration/virtus/attributes/attribute/typecast_spec.rb",
48
55
  "spec/integration/virtus/class_methods/attribute_spec.rb",
49
56
  "spec/integration/virtus/class_methods/attributes_spec.rb",
50
57
  "spec/integration/virtus/class_methods/const_missing_spec.rb",
58
+ "spec/rcov.opts",
51
59
  "spec/spec_helper.rb",
52
60
  "spec/unit/shared/attribute.rb",
53
- "spec/unit/virtus/attributes/array_spec.rb",
54
- "spec/unit/virtus/attributes/attribute_spec.rb",
55
- "spec/unit/virtus/attributes/boolean_spec.rb",
56
- "spec/unit/virtus/attributes/date_spec.rb",
57
- "spec/unit/virtus/attributes/date_time_spec.rb",
58
- "spec/unit/virtus/attributes/decimal_spec.rb",
59
- "spec/unit/virtus/attributes/float_spec.rb",
60
- "spec/unit/virtus/attributes/hash_spec.rb",
61
- "spec/unit/virtus/attributes/integer_spec.rb",
62
- "spec/unit/virtus/attributes/numeric/class_methods/descendants_spec.rb",
63
- "spec/unit/virtus/attributes/object/class_methods/descendants_spec.rb",
64
- "spec/unit/virtus/attributes/string_spec.rb",
65
- "spec/unit/virtus/attributes/time_spec.rb",
61
+ "spec/unit/virtus/attribute/array_spec.rb",
62
+ "spec/unit/virtus/attribute/attribute_spec.rb",
63
+ "spec/unit/virtus/attribute/boolean_spec.rb",
64
+ "spec/unit/virtus/attribute/date_spec.rb",
65
+ "spec/unit/virtus/attribute/date_time_spec.rb",
66
+ "spec/unit/virtus/attribute/decimal_spec.rb",
67
+ "spec/unit/virtus/attribute/float_spec.rb",
68
+ "spec/unit/virtus/attribute/hash_spec.rb",
69
+ "spec/unit/virtus/attribute/integer_spec.rb",
70
+ "spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb",
71
+ "spec/unit/virtus/attribute/object/class_methods/descendants_spec.rb",
72
+ "spec/unit/virtus/attribute/string_spec.rb",
73
+ "spec/unit/virtus/attribute/time_spec.rb",
66
74
  "spec/unit/virtus/class_methods/new_spec.rb",
67
75
  "spec/unit/virtus/determine_type_spec.rb",
68
76
  "spec/unit/virtus/instance_methods/attribute_get_spec.rb",
69
77
  "spec/unit/virtus/instance_methods/attribute_set_spec.rb",
70
78
  "spec/unit/virtus/instance_methods/attributes_spec.rb",
79
+ "tasks/metrics/ci.rake",
80
+ "tasks/metrics/flay.rake",
81
+ "tasks/metrics/flog.rake",
82
+ "tasks/metrics/heckle.rake",
83
+ "tasks/metrics/metric_fu.rake",
84
+ "tasks/metrics/reek.rake",
85
+ "tasks/metrics/roodi.rake",
86
+ "tasks/metrics/yardstick.rake",
87
+ "tasks/spec.rake",
88
+ "tasks/yard.rake",
71
89
  "virtus.gemspec"
72
90
  ]
73
91
  s.homepage = %q{https://github.com/solnic/virtus}
@@ -81,16 +99,13 @@ Gem::Specification.new do |s|
81
99
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
82
100
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
83
101
  s.add_development_dependency(%q<rspec>, ["~> 2.6.0"])
84
- s.add_development_dependency(%q<simplecov>, ["~> 0.4.2"])
85
102
  else
86
103
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
87
104
  s.add_dependency(%q<rspec>, ["~> 2.6.0"])
88
- s.add_dependency(%q<simplecov>, ["~> 0.4.2"])
89
105
  end
90
106
  else
91
107
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
92
108
  s.add_dependency(%q<rspec>, ["~> 2.6.0"])
93
- s.add_dependency(%q<simplecov>, ["~> 0.4.2"])
94
109
  end
95
110
  end
96
111
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: virtus
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Piotr Solnica
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-06-06 00:00:00 Z
13
+ date: 2011-06-09 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: jeweler
@@ -34,17 +34,6 @@ dependencies:
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: simplecov
39
- requirement: &id003 !ruby/object:Gem::Requirement
40
- none: false
41
- requirements:
42
- - - ~>
43
- - !ruby/object:Gem::Version
44
- version: 0.4.2
45
- type: :development
46
- prerelease: false
47
- version_requirements: *id003
48
37
  description: Attributes for your plain ruby objects
49
38
  email:
50
39
  - piotr@rubyverse.com
@@ -60,53 +49,71 @@ files:
60
49
  - .rvmrc
61
50
  - .travis.yml
62
51
  - Gemfile
52
+ - History.txt
63
53
  - LICENSE
64
54
  - README.markdown
65
55
  - Rakefile
66
56
  - VERSION
57
+ - config/flay.yml
58
+ - config/flog.yml
59
+ - config/roodi.yml
60
+ - config/site.reek
61
+ - config/yardstick.yml
67
62
  - lib/virtus.rb
68
- - lib/virtus/attributes/array.rb
69
- - lib/virtus/attributes/attribute.rb
70
- - lib/virtus/attributes/boolean.rb
71
- - lib/virtus/attributes/date.rb
72
- - lib/virtus/attributes/date_time.rb
73
- - lib/virtus/attributes/decimal.rb
74
- - lib/virtus/attributes/float.rb
75
- - lib/virtus/attributes/hash.rb
76
- - lib/virtus/attributes/integer.rb
77
- - lib/virtus/attributes/numeric.rb
78
- - lib/virtus/attributes/object.rb
79
- - lib/virtus/attributes/string.rb
80
- - lib/virtus/attributes/time.rb
81
- - lib/virtus/attributes/typecast/numeric.rb
82
- - lib/virtus/attributes/typecast/time.rb
63
+ - lib/virtus/attribute.rb
64
+ - lib/virtus/attribute/array.rb
65
+ - lib/virtus/attribute/boolean.rb
66
+ - lib/virtus/attribute/date.rb
67
+ - lib/virtus/attribute/date_time.rb
68
+ - lib/virtus/attribute/decimal.rb
69
+ - lib/virtus/attribute/float.rb
70
+ - lib/virtus/attribute/hash.rb
71
+ - lib/virtus/attribute/integer.rb
72
+ - lib/virtus/attribute/numeric.rb
73
+ - lib/virtus/attribute/object.rb
74
+ - lib/virtus/attribute/string.rb
75
+ - lib/virtus/attribute/time.rb
83
76
  - lib/virtus/class_methods.rb
84
77
  - lib/virtus/instance_methods.rb
85
78
  - lib/virtus/support/chainable.rb
79
+ - lib/virtus/typecast/boolean.rb
80
+ - lib/virtus/typecast/numeric.rb
81
+ - lib/virtus/typecast/time.rb
86
82
  - spec/integration/virtus/attributes/attribute/typecast_spec.rb
87
83
  - spec/integration/virtus/class_methods/attribute_spec.rb
88
84
  - spec/integration/virtus/class_methods/attributes_spec.rb
89
85
  - spec/integration/virtus/class_methods/const_missing_spec.rb
86
+ - spec/rcov.opts
90
87
  - spec/spec_helper.rb
91
88
  - spec/unit/shared/attribute.rb
92
- - spec/unit/virtus/attributes/array_spec.rb
93
- - spec/unit/virtus/attributes/attribute_spec.rb
94
- - spec/unit/virtus/attributes/boolean_spec.rb
95
- - spec/unit/virtus/attributes/date_spec.rb
96
- - spec/unit/virtus/attributes/date_time_spec.rb
97
- - spec/unit/virtus/attributes/decimal_spec.rb
98
- - spec/unit/virtus/attributes/float_spec.rb
99
- - spec/unit/virtus/attributes/hash_spec.rb
100
- - spec/unit/virtus/attributes/integer_spec.rb
101
- - spec/unit/virtus/attributes/numeric/class_methods/descendants_spec.rb
102
- - spec/unit/virtus/attributes/object/class_methods/descendants_spec.rb
103
- - spec/unit/virtus/attributes/string_spec.rb
104
- - spec/unit/virtus/attributes/time_spec.rb
89
+ - spec/unit/virtus/attribute/array_spec.rb
90
+ - spec/unit/virtus/attribute/attribute_spec.rb
91
+ - spec/unit/virtus/attribute/boolean_spec.rb
92
+ - spec/unit/virtus/attribute/date_spec.rb
93
+ - spec/unit/virtus/attribute/date_time_spec.rb
94
+ - spec/unit/virtus/attribute/decimal_spec.rb
95
+ - spec/unit/virtus/attribute/float_spec.rb
96
+ - spec/unit/virtus/attribute/hash_spec.rb
97
+ - spec/unit/virtus/attribute/integer_spec.rb
98
+ - spec/unit/virtus/attribute/numeric/class_methods/descendants_spec.rb
99
+ - spec/unit/virtus/attribute/object/class_methods/descendants_spec.rb
100
+ - spec/unit/virtus/attribute/string_spec.rb
101
+ - spec/unit/virtus/attribute/time_spec.rb
105
102
  - spec/unit/virtus/class_methods/new_spec.rb
106
103
  - spec/unit/virtus/determine_type_spec.rb
107
104
  - spec/unit/virtus/instance_methods/attribute_get_spec.rb
108
105
  - spec/unit/virtus/instance_methods/attribute_set_spec.rb
109
106
  - spec/unit/virtus/instance_methods/attributes_spec.rb
107
+ - tasks/metrics/ci.rake
108
+ - tasks/metrics/flay.rake
109
+ - tasks/metrics/flog.rake
110
+ - tasks/metrics/heckle.rake
111
+ - tasks/metrics/metric_fu.rake
112
+ - tasks/metrics/reek.rake
113
+ - tasks/metrics/roodi.rake
114
+ - tasks/metrics/yardstick.rake
115
+ - tasks/spec.rake
116
+ - tasks/yard.rake
110
117
  - virtus.gemspec
111
118
  homepage: https://github.com/solnic/virtus
112
119
  licenses: []
@@ -121,6 +128,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
121
128
  requirements:
122
129
  - - ">="
123
130
  - !ruby/object:Gem::Version
131
+ hash: 403965839
132
+ segments:
133
+ - 0
124
134
  version: "0"
125
135
  required_rubygems_version: !ruby/object:Gem::Requirement
126
136
  none: false
@@ -1,8 +0,0 @@
1
- module Virtus
2
- module Attributes
3
- class Array < Object
4
- primitive ::Array
5
- complex true
6
- end # Integer
7
- end # Attributes
8
- end # Virtus
@@ -1,214 +0,0 @@
1
- module Virtus
2
- module Attributes
3
- class Attribute
4
- attr_reader :name, :model, :options, :instance_variable_name,
5
- :reader_visibility, :writer_visibility
6
-
7
- OPTIONS = [ :primitive, :complex, :accessor, :reader, :writer ].freeze
8
-
9
- DEFAULT_ACCESSOR = :public.freeze
10
-
11
- class << self
12
- # Returns an array of valid options
13
- #
14
- # @return [Array]
15
- # the array of valid option names
16
- #
17
- # @api public
18
- def accepted_options
19
- @accepted_options ||= []
20
- end
21
-
22
- # Defines which options are valid for a given attribute class.
23
- #
24
- # Example:
25
- #
26
- # class MyAttribute < Virtus::Attributes::Object
27
- # accept_options :foo, :bar
28
- # end
29
- #
30
- # @api public
31
- def accept_options(*args)
32
- accepted_options.concat(args)
33
-
34
- # create methods for each new option
35
- args.each do |attribute_option|
36
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
37
- def self.#{attribute_option}(value = Undefined) # def self.unique(value = Undefined)
38
- return @#{attribute_option} if value.equal?(Undefined) # return @unique if value.equal?(Undefined)
39
- @#{attribute_option} = value # @unique = value
40
- end # end
41
- RUBY
42
- end
43
-
44
- descendants.each { |descendant| descendant.accepted_options.concat(args) }
45
- end
46
-
47
- # Returns all the descendant classes
48
- #
49
- # @return [Array]
50
- # the array of descendants
51
- #
52
- # @api public
53
- def descendants
54
- @descendants ||= []
55
- end
56
-
57
- # Returns default options hash for a give attribute class.
58
- #
59
- # @return [Hash]
60
- # a hash of default option values
61
- #
62
- # @api public
63
- def options
64
- options = {}
65
- accepted_options.each do |method|
66
- value = send(method)
67
- options[method] = value unless value.nil?
68
- end
69
- options
70
- end
71
-
72
- # Adds descendant to descendants array and inherits default options
73
- #
74
- # @api private
75
- def inherited(descendant)
76
- descendants << descendant
77
- descendant.accepted_options.concat(accepted_options)
78
- options.each { |key, value| descendant.send(key, value) }
79
- end
80
- end
81
-
82
- accept_options *OPTIONS
83
-
84
- # Returns if an attribute is a complex one.
85
- #
86
- # @return [TrueClass, FalseClass]
87
- #
88
- # @api semipublic
89
- def complex?
90
- options[:complex]
91
- end
92
-
93
- # Initializes an attribute instance
94
- #
95
- # @param [Symbol] name
96
- # the name of an attribute
97
- #
98
- # @param [Class] model
99
- # the object's class
100
- #
101
- # @param [Hash] options
102
- # hash of extra options which overrides defaults set on an attribute class
103
- #
104
- # @api private
105
- def initialize(name, model, options = {})
106
- @name = name
107
- @model = model
108
- @options = self.class.options.merge(options).freeze
109
-
110
- @instance_variable_name = "@#{@name}".freeze
111
-
112
- default_accessor = @options.fetch(:accessor, DEFAULT_ACCESSOR)
113
- @reader_visibility = @options.fetch(:reader, default_accessor)
114
- @writer_visibility = @options.fetch(:writer, default_accessor)
115
-
116
- _create_reader
117
- _create_writer
118
- end
119
-
120
- # Returns if the given value's class is an attribute's primitive
121
- #
122
- # @return [TrueClass, FalseClass]
123
- #
124
- # @api private
125
- def primitive?(value)
126
- value.kind_of?(self.class.primitive)
127
- end
128
-
129
- # Converts the given value to the primitive type unless it's already
130
- # the primitive or nil
131
- #
132
- # @param [Object] value
133
- # the value
134
- #
135
- # @api private
136
- def typecast(value, model = nil)
137
- if value.nil? || primitive?(value)
138
- value
139
- else
140
- typecast_to_primitive(value)
141
- end
142
- end
143
-
144
- # Converts the given value to the primitive type
145
- #
146
- # @api private
147
- def typecast_to_primitive(value, model)
148
- value
149
- end
150
-
151
- # Returns value of an attribute for the given model
152
- #
153
- # @api private
154
- def get(model)
155
- get!(model)
156
- end
157
-
158
- # Returns the instance variable of the attribute
159
- #
160
- # @api private
161
- def get!(model)
162
- model.instance_variable_get(instance_variable_name)
163
- end
164
-
165
- # Sets the value on the model
166
- #
167
- # @api private
168
- def set(model, value)
169
- return if value.nil?
170
- set!(model, typecast(value, model))
171
- end
172
-
173
- # Sets instance variable of the attribute
174
- #
175
- # @api private
176
- def set!(model, value)
177
- model.instance_variable_set(instance_variable_name, value)
178
- end
179
-
180
- # Creates an attribute reader method
181
- #
182
- # @api private
183
- def _create_reader
184
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
185
- chainable(:attribute) do
186
- #{reader_visibility}
187
-
188
- def #{name}
189
- return #{instance_variable_name} if defined?(#{instance_variable_name})
190
- attribute = self.class.attributes[#{name.inspect}]
191
- #{instance_variable_name} = attribute ? attribute.get(self) : nil
192
- end
193
- end
194
- RUBY
195
-
196
- end
197
-
198
- # Creates an attribute writer method
199
- #
200
- # @api private
201
- def _create_writer
202
- model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
203
- chainable(:attribute) do
204
- #{writer_visibility}
205
-
206
- def #{name}=(value)
207
- self.class.attributes[#{name.inspect}].set(self, value)
208
- end
209
- end
210
- RUBY
211
- end
212
- end # Attribute
213
- end # Attributes
214
- end # Virtus