virtus 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,7 +13,7 @@ module Virtus
13
13
  # end
14
14
  #
15
15
  # post = Post.new(:published => false)
16
- # post.published? # => false
16
+ # post.published? # => false
17
17
  #
18
18
  class Boolean < Object
19
19
  primitive TrueClass
@@ -21,14 +21,14 @@ module Virtus
21
21
  # Returns if the given value is either true or false
22
22
  #
23
23
  # @example
24
- # Virtus::Attribute::Boolean.primitive?(true) # => true
25
- # Virtus::Attribute::Boolean.primitive?(false) # => true
26
- # Virtus::Attribute::Boolean.primitive?(1) # => false
27
- # Virtus::Attribute::Boolean.primitive?('true') # => false
24
+ # Virtus::Attribute::Boolean.primitive?(true) # => true
25
+ # Virtus::Attribute::Boolean.primitive?(false) # => true
26
+ # Virtus::Attribute::Boolean.primitive?(1) # => false
27
+ # Virtus::Attribute::Boolean.primitive?('true') # => false
28
28
  #
29
- # @return [TrueClass,FalseClass]
29
+ # @return [Boolean]
30
30
  #
31
- # @api semipublic
31
+ # @api public
32
32
  def self.primitive?(value)
33
33
  value.equal?(true) || value.equal?(false)
34
34
  end
@@ -37,7 +37,7 @@ module Virtus
37
37
  #
38
38
  # @see Virtus::Typecast::Boolean.call
39
39
  #
40
- # @return [TrueClass,FalseClass]
40
+ # @return [Boolean]
41
41
  #
42
42
  # @api private
43
43
  def typecast_to_primitive(value)
@@ -46,7 +46,9 @@ module Virtus
46
46
 
47
47
  # Creates standard and boolean attribute reader methods
48
48
  #
49
- # @return [NilClass]
49
+ # @param [Class] model
50
+ #
51
+ # @return [self]
50
52
  #
51
53
  # @api private
52
54
  def add_reader_method(model)
@@ -56,15 +58,17 @@ module Virtus
56
58
  method_name = "#{name}?"
57
59
 
58
60
  model.class_eval <<-RUBY, __FILE__, __LINE__ + 1
59
- module AttributeMethods
60
- def #{method_name}
61
- #{name}
62
- end
63
- end
64
- include AttributeMethods
61
+ module AttributeMethods # module AttributeMethods
62
+ def #{method_name} # def active?
63
+ #{name} # @active
64
+ end # end
65
+ end # end
66
+ include AttributeMethods # include AttributeMethods
65
67
  RUBY
66
68
 
67
69
  model.send(reader_visibility, method_name)
70
+
71
+ self
68
72
  end
69
73
 
70
74
  end # class Boolean
@@ -26,6 +26,8 @@ module Virtus
26
26
 
27
27
  # @see Virtus::Typecast::Time.to_datetime
28
28
  #
29
+ # @return [DateTime]
30
+ #
29
31
  # @api private
30
32
  def typecast_to_primitive(value)
31
33
  Typecast::Time.to_datetime(value)
@@ -16,6 +16,8 @@ module Virtus
16
16
 
17
17
  # @see Virtus::Typecast::Numeric.to_d
18
18
  #
19
+ # @return [BigDecimal]
20
+ #
19
21
  # @api private
20
22
  def typecast_to_primitive(value)
21
23
  Typecast::Numeric.to_d(value)
@@ -25,6 +25,8 @@ module Virtus
25
25
 
26
26
  # @see Virtus::Typecast::Numeric.to_f
27
27
  #
28
+ # @return [Float]
29
+ #
28
30
  # @api private
29
31
  def typecast_to_primitive(value)
30
32
  Typecast::Numeric.to_f(value)
@@ -22,6 +22,8 @@ module Virtus
22
22
 
23
23
  # @see Virtus::Typecast::Numeric.to_i
24
24
  #
25
+ # @return [Integer]
26
+ #
25
27
  # @api private
26
28
  def typecast_to_primitive(value)
27
29
  Typecast::Numeric.to_i(value)
@@ -19,6 +19,8 @@ module Virtus
19
19
 
20
20
  # @see Virtus::Typecast::String.call
21
21
  #
22
+ # @return [String]
23
+ #
22
24
  # @api private
23
25
  def typecast_to_primitive(value)
24
26
  Virtus::Typecast::String.call(value)
@@ -16,7 +16,12 @@ module Virtus
16
16
  #
17
17
  # # typecasting from a hash
18
18
  # Post.new(:published_at => {
19
- # :year => 2011, :month => 6, :day => 9, :hour => 11, :minutes => 8 })
19
+ # :year => 2011,
20
+ # :month => 6,
21
+ # :day => 9,
22
+ # :hour => 11,
23
+ # :minutes => 8
24
+ # })
20
25
  #
21
26
  # # typecasting from an object which implements #to_time
22
27
  # Post.new(:published_at => DateTime.now)
@@ -26,6 +31,8 @@ module Virtus
26
31
 
27
32
  # @see Virtus::Typecast::Time.to_time
28
33
  #
34
+ # @return [Time]
35
+ #
29
36
  # @api private
30
37
  def typecast_to_primitive(value)
31
38
  Typecast::Time.to_time(value)
@@ -28,7 +28,7 @@ module Virtus
28
28
  #
29
29
  # @api public
30
30
  def attribute(name, type, options = {})
31
- attribute = Virtus.determine_type(type).new(name, options)
31
+ attribute = Attribute.determine_type(type).new(name, options)
32
32
 
33
33
  attribute.add_reader_method(self)
34
34
  attribute.add_writer_method(self)
@@ -49,12 +49,11 @@ module Virtus
49
49
  # attribute :age, Integer
50
50
  # end
51
51
  #
52
- # User.attributes # =>
52
+ # User.attributes # =>
53
53
  #
54
54
  # TODO: implement inspect so the output is not cluttered - solnic
55
55
  #
56
- # @return [Hash]
57
- # an attributes hash indexed by attribute names
56
+ # @return [AttributeSet]
58
57
  #
59
58
  # @api public
60
59
  def attributes
@@ -79,7 +78,7 @@ module Virtus
79
78
  #
80
79
  # @api private
81
80
  def const_missing(name)
82
- Virtus.determine_type(name) || super
81
+ Attribute.determine_type(name) || super
83
82
  end
84
83
 
85
84
  end # module ClassMethods
@@ -8,7 +8,7 @@ module Virtus
8
8
  # @param [#to_hash] attributes
9
9
  # the attributes hash to be set
10
10
  #
11
- # @return [Object]
11
+ # @return [undefined]
12
12
  #
13
13
  # @api private
14
14
  def initialize(attributes = {})
@@ -25,7 +25,7 @@ module Virtus
25
25
  # end
26
26
  #
27
27
  # user = User.new(:name => 'John')
28
- # user[:name] # => "john"
28
+ # user[:name] # => "John"
29
29
  #
30
30
  # @param [Symbol] name
31
31
  # a name of an attribute
@@ -48,8 +48,8 @@ module Virtus
48
48
  # end
49
49
  #
50
50
  # user = User.new
51
- # user[:name] = "john" # => "john"
52
- # user.name # => "john"
51
+ # user[:name] = "John" # => "John"
52
+ # user.name # => "John"
53
53
  #
54
54
  # @param [Symbol] name
55
55
  # a name of an attribute
@@ -76,10 +76,9 @@ module Virtus
76
76
  # end
77
77
  #
78
78
  # user = User.new(:name => 'John', :age => 28)
79
- # user.attributes # => { :name => 'John', :age => 28 }
79
+ # user.attributes # => { :name => 'John', :age => 28 }
80
80
  #
81
81
  # @return [Hash]
82
- # the attributes
83
82
  #
84
83
  # @api public
85
84
  def attributes
@@ -110,7 +109,6 @@ module Virtus
110
109
  # a hash of attribute values to be set on an object
111
110
  #
112
111
  # @return [Hash]
113
- # the attributes
114
112
  #
115
113
  # @api public
116
114
  def attributes=(attributes)
@@ -125,6 +123,8 @@ module Virtus
125
123
  #
126
124
  # @see Virtus::InstanceMethods#[]
127
125
  #
126
+ # @return [Object]
127
+ #
128
128
  # @api private
129
129
  def attribute_get(name)
130
130
  __send__(name)
@@ -134,6 +134,8 @@ module Virtus
134
134
  #
135
135
  # @see Virtus::InstanceMethods#[]=
136
136
  #
137
+ # @return [Object]
138
+ #
137
139
  # @api private
138
140
  def attribute_set(name, value)
139
141
  __send__("#{name}=", value)
@@ -3,27 +3,41 @@ module Virtus
3
3
  # A module that adds descendant tracking to a class
4
4
  module DescendantsTracker
5
5
 
6
- # Hook called when class is inherited
6
+ # Return the descendants of this class
7
+ #
8
+ # @return [Array<Class>]
9
+ #
10
+ # @api private
11
+ def descendants
12
+ @descendants ||= []
13
+ end
14
+
15
+ # Add the descendant to this class and the superclass
7
16
  #
8
17
  # @param [Class] descendant
9
18
  #
10
19
  # @return [self]
11
20
  #
12
21
  # @api private
13
- def inherited(descendant)
22
+ def add_descendant(descendant)
14
23
  superclass = self.superclass
15
- superclass.inherited(descendant) if superclass.respond_to?(:descendants)
24
+ superclass.add_descendant(descendant) if superclass.respond_to?(:add_descendant)
16
25
  descendants.unshift(descendant)
17
26
  self
18
27
  end
19
28
 
20
- # Return the descendants of this class
29
+ private
30
+
31
+ # Hook called when class is inherited
21
32
  #
22
- # @return [Array<Class>]
33
+ # @param [Class] descendant
34
+ #
35
+ # @return [self]
23
36
  #
24
37
  # @api private
25
- def descendants
26
- @descendants ||= []
38
+ def inherited(descendant)
39
+ super
40
+ add_descendant(descendant)
27
41
  end
28
42
 
29
43
  end # module DescendantsTracker
@@ -5,23 +5,23 @@ module Virtus
5
5
  # See TRUE_VALUES and FALSE_VALUES constants for a reference.
6
6
  class Boolean
7
7
 
8
- TRUE_VALUES = [ 1, '1', 't', 'T', 'true', 'TRUE' ].freeze
9
- FALSE_VALUES = [ 0, '0', 'f', 'F', 'false', 'FALSE' ].freeze
8
+ TRUE_VALUES = %w[ 1 t true ].freeze
9
+ FALSE_VALUES = %w[ 0 f false ].freeze
10
10
  BOOLEAN_MAP = Hash[ TRUE_VALUES.product([ true ]) + FALSE_VALUES.product([ false ]) ].freeze
11
11
 
12
12
  # Typecast value to TrueClass or FalseClass
13
13
  #
14
14
  # @example
15
- # Virtus::Typecast::Boolean.call('T') # => true
16
- # Virtus::Typecast::Boolean.call('F') # => false
15
+ # Virtus::Typecast::Boolean.call('T') # => true
16
+ # Virtus::Typecast::Boolean.call('F') # => false
17
17
  #
18
- # @param [Integer, String]
18
+ # @param [#to_s]
19
19
  #
20
- # @return [TrueClass, FalseClass]
20
+ # @return [Boolean]
21
21
  #
22
22
  # @api public
23
23
  def self.call(value)
24
- BOOLEAN_MAP.fetch(value, value)
24
+ BOOLEAN_MAP.fetch(value.to_s.downcase, value)
25
25
  end
26
26
 
27
27
  end # class Boolean
@@ -9,8 +9,8 @@ module Virtus
9
9
  # Typecast value to integer
10
10
  #
11
11
  # @example
12
- # Virtus::Typecast::Numeric.to_i('1') # => 1
13
- # Virtus::Typecast::Numeric.to_i(1.2) # => 1
12
+ # Virtus::Typecast::Numeric.to_i('1') # => 1
13
+ # Virtus::Typecast::Numeric.to_i(1.2) # => 1
14
14
  #
15
15
  # @param [Object] value
16
16
  #
@@ -24,8 +24,8 @@ module Virtus
24
24
  # Typecast value to float
25
25
  #
26
26
  # @example
27
- # Virtus::Typecast::Numeric.to_f('1.2') # => 1.2
28
- # Virtus::Typecast::Numeric.to_f(1) # => 1.0
27
+ # Virtus::Typecast::Numeric.to_f('1.2') # => 1.2
28
+ # Virtus::Typecast::Numeric.to_f(1) # => 1.0
29
29
  #
30
30
  # @param [Object] value
31
31
  #
@@ -39,8 +39,8 @@ module Virtus
39
39
  # Typecast value to decimal
40
40
  #
41
41
  # @example
42
- # Virtus::Typecast::Numeric.to_d('1.2') # => #<BigDecimal:b72157d4,'0.12E1',8(8)>
43
- # Virtus::Typecast::Numeric.to_d(1) # => #<BigDecimal:b7212e08,'0.1E1',4(8)>
42
+ # Virtus::Typecast::Numeric.to_d('1.2') # => #<BigDecimal:b72157d4,'0.12E1',8(8)>
43
+ # Virtus::Typecast::Numeric.to_d(1) # => #<BigDecimal:b7212e08,'0.1E1',4(8)>
44
44
  #
45
45
  # @param [Object] value
46
46
  #
@@ -55,8 +55,6 @@ module Virtus
55
55
  end
56
56
  end
57
57
 
58
- private
59
-
60
58
  # Match numeric string
61
59
  #
62
60
  # @param [#to_str, Numeric] value
@@ -82,6 +80,8 @@ module Virtus
82
80
  end
83
81
  end
84
82
 
83
+ private_class_method :call
84
+
85
85
  end # class Numeric
86
86
  end # module Typecast
87
87
  end # module Virtus
@@ -7,8 +7,8 @@ module Virtus
7
7
  # Typecast value to a string
8
8
  #
9
9
  # @example
10
- # Virtus::Typecast::String.call(1) # => '1'
11
- # Virtus::Typecast::String.call([]) # => '[]'
10
+ # Virtus::Typecast::String.call(1) # => "1"
11
+ # Virtus::Typecast::String.call([]) # => "[]"
12
12
  #
13
13
  # @param [Object] value
14
14
  #
@@ -19,7 +19,7 @@ module Virtus
19
19
  # Virtus::Typecast::Time.to_time('2011/06/09 12:01')
20
20
  # # => Thu Jun 09 12:01:00 +0200 2011
21
21
  #
22
- # @param [Hash, #to_mash, #to_s] value
22
+ # @param [#to_hash, #to_s] value
23
23
  # value to be typecast
24
24
  #
25
25
  # @return [Time]
@@ -38,7 +38,7 @@ module Virtus
38
38
  # Virtus::Typecast::Time.to_date('2011/06/09')
39
39
  # # => #<Date: 4911443/2,0,2299161>
40
40
  #
41
- # @param [Hash, #to_mash, #to_s] value
41
+ # @param [#to_hash, #to_s] value
42
42
  # value to be typecast
43
43
  #
44
44
  # @return [Date]
@@ -57,7 +57,7 @@ module Virtus
57
57
  # Virtus::Typecast::Time.to_datetime('2011/06/09 12:01')
58
58
  # # => #<DateTime: 3536239681/1440,0,2299161>
59
59
  #
60
- # @param [Hash, #to_mash, #to_s] value
60
+ # @param [#to_hash, #to_s] value
61
61
  # value to be typecast
62
62
  #
63
63
  # @return [DateTime]
@@ -68,15 +68,21 @@ module Virtus
68
68
  call(value, :to_datetime)
69
69
  end
70
70
 
71
- private
72
-
71
+ # Coerce the value into a Date, Time or DateTime object
72
+ #
73
+ # @param [#to_hash, #to_s] value
74
+ #
75
+ # @param [Symbol] method
76
+ #
77
+ # @return [Object]
78
+ #
73
79
  # @api private
74
80
  def self.call(value, method)
75
81
  return value.send(method) if value.respond_to?(method)
76
82
 
77
83
  begin
78
- if value.kind_of?(::Hash)
79
- from_hash(value, method)
84
+ if value.respond_to?(:to_hash)
85
+ from_hash(value.to_hash, method)
80
86
  else
81
87
  from_string(value.to_s, method)
82
88
  end
@@ -85,70 +91,90 @@ module Virtus
85
91
  end
86
92
  end
87
93
 
94
+ private_class_method :call
95
+
96
+ # Coerce the string into a Date, Time or DateTime object
97
+ #
98
+ # @param [String] value
99
+ #
100
+ # @param [Symbol] method
101
+ #
102
+ # @return [Object]
103
+ #
88
104
  # @api private
89
105
  def self.from_string(value, method)
90
- METHOD_TO_CLASS[method].parse(value.to_s)
106
+ METHOD_TO_CLASS[method].parse(value)
91
107
  end
92
108
 
109
+ private_class_method :from_string
110
+
111
+ # Coerce the Hash into a Date, Time or DateTime object
112
+ #
113
+ # @param [Hash] value
114
+ #
115
+ # @param [Symbol] method
116
+ #
117
+ # @return [Object]
118
+ #
93
119
  # @api private
94
120
  def self.from_hash(value, method)
95
121
  send("hash_#{method}", value)
96
122
  end
97
123
 
124
+ private_class_method :from_hash
125
+
98
126
  # Creates a Time instance from a Hash
99
127
  #
100
128
  # Valid keys are: :year, :month, :day, :hour, :min, :sec
101
129
  #
102
- # @param [Hash, #to_mash] value
103
- # value to be typecast
130
+ # @param [Hash] value
104
131
  #
105
132
  # @return [Time]
106
- # Time constructed from hash
107
133
  #
108
134
  # @api private
109
135
  def self.hash_to_time(value)
110
136
  ::Time.local(*extract(value))
111
137
  end
112
138
 
139
+ private_class_method :hash_to_time
140
+
113
141
  # Creates a Date instance from a Hash
114
142
  #
115
143
  # Valid keys are: :year, :month, :day, :hour
116
144
  #
117
- # @param [Hash, #to_mash] value
118
- # value to be typecast
145
+ # @param [Hash] value
119
146
  #
120
147
  # @return [Date]
121
- # Date constructed from hash
122
148
  #
123
149
  # @api private
124
150
  def self.hash_to_date(value)
125
151
  ::Date.new(*extract(value).first(3))
126
152
  end
127
153
 
154
+ private_class_method :hash_to_date
155
+
128
156
  # Creates a DateTime instance from a Hash
129
157
  #
130
158
  # Valid keys are: :year, :month, :day, :hour, :min, :sec
131
159
  #
132
- # @param [Hash, #to_mash] value
133
- # value to be typecast
160
+ # @param [Hash] value
134
161
  #
135
162
  # @return [DateTime]
136
- # DateTime constructed from hash
137
163
  #
138
164
  # @api private
139
165
  def self.hash_to_datetime(value)
140
166
  ::DateTime.new(*extract(value))
141
167
  end
142
168
 
143
- # Extracts the given args from the hash
169
+ private_class_method :hash_to_datetime
170
+
171
+ # Extracts the given args from a Hash
144
172
  #
145
173
  # If a value does not exist, it uses the value of Time.now
146
174
  #
147
- # @param [Hash, #to_mash] value
148
- # value to extract time args from
175
+ # @param [Hash] value
149
176
  #
150
177
  # @return [Array]
151
- # Extracted values
152
178
  #
153
179
  # @api private
154
180
  def self.extract(value)
@@ -159,6 +185,8 @@ module Virtus
159
185
  end
160
186
  end
161
187
 
188
+ private_class_method :extract
189
+
162
190
  end # class Time
163
191
  end # module Typecast
164
192
  end # module Virtus