fast_attributes 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +13 -0
- data/README.md +22 -3
- data/lib/fast_attributes.rb +1 -0
- data/lib/fast_attributes/builder.rb +29 -10
- data/lib/fast_attributes/default_attributes.rb +33 -0
- data/lib/fast_attributes/version.rb +1 -1
- data/spec/fast_attributes_spec.rb +33 -0
- data/spec/fixtures/classes.rb +11 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c90efa52db1c0c48916b37d6229a101e99e32fb
|
4
|
+
data.tar.gz: dfd651948c3f0700ccfb4d421fb1ad47009da8df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2eec805647af281fa932263b04cbbdcb3aff1f6d7e564e9a48ec5480f064e59258e493d4be24685e3f104ffa1e8ac19dc6bf972386c838b7b86bbad4105cdb8
|
7
|
+
data.tar.gz: 60c51d7ccba9ca05ca50852bc3943d90b0081131a7756446d91de9b454bfa7f0c1bf438cef4c7a0eac1b49cb11eddb53c0995e5dff4c4091578fcdcee56f9e74
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
**0.8.0 (September 15, 2016)**
|
2
|
+
* Support of default values [Phil Schalm](https://github.com/pnomolos)
|
3
|
+
```ruby
|
4
|
+
class Product
|
5
|
+
extend FastAttributes
|
6
|
+
|
7
|
+
define_attributes initialize: true, attributes: true do
|
8
|
+
attribute :title, String, default: "Book"
|
9
|
+
attribute :price, Float, default: 10
|
10
|
+
end
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
1
14
|
**0.7.0 (August 31, 2014)**
|
2
15
|
* Support `boolean` data type as a lenient type.
|
3
16
|
```ruby
|
data/README.md
CHANGED
@@ -107,6 +107,25 @@ book.attributes
|
|
107
107
|
"finished"=>
|
108
108
|
#<DateTime: 1937-08-20T12:35:00+00:00 ((2428766j,45300s,0n),+0s,2299161j)>}
|
109
109
|
```
|
110
|
+
|
111
|
+
## Default values
|
112
|
+
|
113
|
+
Requires `define_attributes` to be used with `initialize: true` (this is where the default values are set):
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
class Book
|
117
|
+
extend FastAttributes
|
118
|
+
|
119
|
+
define_attributes initialize: true do
|
120
|
+
attribute :author, String, default: "Some String"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
book = Book.new
|
125
|
+
book.attributes
|
126
|
+
{"author" => "Some String"}
|
127
|
+
```
|
128
|
+
|
110
129
|
## Custom Type
|
111
130
|
It's easy to add a custom attribute type.
|
112
131
|
```ruby
|
@@ -123,7 +142,7 @@ book.author
|
|
123
142
|
# => #<OpenStruct name="Rowling">
|
124
143
|
```
|
125
144
|
|
126
|
-
Notice, that second parameter is a string. It's necessary because this code is compiled into a ruby method in runtime. The placeholder `%s` represents a value which this method accepts.
|
145
|
+
Notice, that second parameter is a string. It's necessary because this code is compiled into a ruby method in runtime. The placeholder `%s` represents a value which this method accepts.
|
127
146
|
|
128
147
|
It's possible to refer to a placeholder several times.
|
129
148
|
```ruby
|
@@ -183,7 +202,7 @@ FastAttributes.type_cast String do # begin
|
|
183
202
|
# case String
|
184
203
|
from 'nil', to: 'nil' # when nil then nil
|
185
204
|
from 'String', to: '%s' # when String then %s
|
186
|
-
otherwise 'String(%s)' # else String(%s)
|
205
|
+
otherwise 'String(%s)' # else String(%s)
|
187
206
|
# end
|
188
207
|
on_error 'TypeError', act: 'nil' # rescue TypeError => e
|
189
208
|
# nil
|
@@ -210,7 +229,7 @@ end
|
|
210
229
|
order = Order.new
|
211
230
|
order.terms_of_service = 'yes'
|
212
231
|
order.terms_of_service
|
213
|
-
# => true
|
232
|
+
# => true
|
214
233
|
order.terms_of_service = 'no'
|
215
234
|
order.terms_of_service
|
216
235
|
# => false
|
data/lib/fast_attributes.rb
CHANGED
@@ -4,6 +4,7 @@ require 'time'
|
|
4
4
|
require 'fast_attributes/version'
|
5
5
|
require 'fast_attributes/builder'
|
6
6
|
require 'fast_attributes/type_cast'
|
7
|
+
require 'fast_attributes/default_attributes'
|
7
8
|
|
8
9
|
module FastAttributes
|
9
10
|
TRUE_VALUES = {true => nil, 1 => nil, '1' => nil, 't' => nil, 'T' => nil, 'true' => nil, 'TRUE' => nil, 'on' => nil, 'ON' => nil}
|
@@ -10,17 +10,24 @@ module FastAttributes
|
|
10
10
|
@methods = Module.new
|
11
11
|
end
|
12
12
|
|
13
|
-
def attribute(*attributes, type)
|
13
|
+
def attribute(*attributes, type, options)
|
14
|
+
unless options.is_a?(Hash)
|
15
|
+
(attributes ||= []) << type
|
16
|
+
type = options
|
17
|
+
options = {}
|
18
|
+
end
|
19
|
+
|
14
20
|
unless FastAttributes.type_exists?(type)
|
15
21
|
raise UnsupportedTypeError, %(Unsupported attribute type "#{type.inspect}")
|
16
22
|
end
|
17
23
|
|
18
|
-
@attributes << [attributes, type]
|
24
|
+
@attributes << [attributes, type, options || {}]
|
19
25
|
end
|
20
26
|
|
21
27
|
def compile!
|
22
28
|
compile_getter
|
23
29
|
compile_setter
|
30
|
+
set_defaults
|
24
31
|
|
25
32
|
if @options[:initialize]
|
26
33
|
compile_initialize
|
@@ -36,17 +43,17 @@ module FastAttributes
|
|
36
43
|
private
|
37
44
|
|
38
45
|
def compile_getter
|
39
|
-
each_attribute do |attribute,
|
46
|
+
each_attribute do |attribute, *|
|
40
47
|
@methods.module_eval <<-EOS, __FILE__, __LINE__ + 1
|
41
|
-
def #{attribute}
|
42
|
-
@#{attribute}
|
43
|
-
end
|
48
|
+
def #{attribute} # def name
|
49
|
+
@#{attribute} # @name
|
50
|
+
end # end
|
44
51
|
EOS
|
45
52
|
end
|
46
53
|
end
|
47
54
|
|
48
55
|
def compile_setter
|
49
|
-
each_attribute do |attribute, type
|
56
|
+
each_attribute do |attribute, type, *|
|
50
57
|
type_cast = FastAttributes.get_type_casting(type)
|
51
58
|
method_body = type_cast.compile_method_body(attribute, 'value')
|
52
59
|
|
@@ -59,9 +66,15 @@ module FastAttributes
|
|
59
66
|
end
|
60
67
|
|
61
68
|
def compile_initialize
|
69
|
+
attribute_string = if FastAttributes.default_attributes(@klass).empty?
|
70
|
+
"attributes"
|
71
|
+
else
|
72
|
+
"FastAttributes.default_attributes(self.class).merge(attributes)"
|
73
|
+
end
|
74
|
+
|
62
75
|
@methods.module_eval <<-EOS, __FILE__, __LINE__ + 1
|
63
76
|
def initialize(attributes = {})
|
64
|
-
|
77
|
+
#{attribute_string}.each do |name, value|
|
65
78
|
public_send("\#{name}=", value)
|
66
79
|
end
|
67
80
|
end
|
@@ -90,10 +103,16 @@ module FastAttributes
|
|
90
103
|
@klass.send(:include, @methods)
|
91
104
|
end
|
92
105
|
|
106
|
+
def set_defaults
|
107
|
+
each_attribute do |attribute, type, options|
|
108
|
+
FastAttributes.add_default_attribute(@klass, attribute, options[:default]) if options[:default]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
93
112
|
def each_attribute
|
94
|
-
@attributes.each do |attributes, type|
|
113
|
+
@attributes.each do |attributes, type, options = {}|
|
95
114
|
attributes.each do |attribute|
|
96
|
-
yield attribute, type
|
115
|
+
yield attribute, type, options
|
97
116
|
end
|
98
117
|
end
|
99
118
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module FastAttributes
|
2
|
+
class << self
|
3
|
+
SINGLETON_CLASSES = [::NilClass, ::TrueClass, ::FalseClass, ::Numeric, ::Symbol].freeze
|
4
|
+
|
5
|
+
def default_attributes(klass)
|
6
|
+
return {} unless (@default_attributes || {})[klass]
|
7
|
+
@default_attributes[klass].each_with_object({}) do |(attribute, value), memo|
|
8
|
+
memo[attribute] = if value.respond_to?(:call)
|
9
|
+
value.call
|
10
|
+
elsif cloneable?(value)
|
11
|
+
value.clone
|
12
|
+
else
|
13
|
+
value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_default_attribute(klass, attribute, value)
|
19
|
+
@default_attributes ||= {}
|
20
|
+
@default_attributes[klass] ||= {}
|
21
|
+
@default_attributes[klass][attribute] = value
|
22
|
+
end
|
23
|
+
|
24
|
+
def cloneable?(value)
|
25
|
+
case value
|
26
|
+
when *SINGLETON_CLASSES
|
27
|
+
false
|
28
|
+
else
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -364,4 +364,37 @@ describe FastAttributes do
|
|
364
364
|
end
|
365
365
|
end
|
366
366
|
end
|
367
|
+
|
368
|
+
describe "default attributes" do
|
369
|
+
it "sets the default values" do
|
370
|
+
class_with_defaults = ClassWithDefaults.new
|
371
|
+
|
372
|
+
expect(class_with_defaults.title).to eq('a title')
|
373
|
+
expect(class_with_defaults.pages).to be(10)
|
374
|
+
expect(class_with_defaults.authors).to eq([1, 2, 4])
|
375
|
+
end
|
376
|
+
|
377
|
+
it "allows you to override default values" do
|
378
|
+
class_with_defaults = ClassWithDefaults.new(title: 'Something', authors: [1, 5, 7])
|
379
|
+
|
380
|
+
expect(class_with_defaults.title).to eq('Something')
|
381
|
+
expect(class_with_defaults.pages).to be(10)
|
382
|
+
expect(class_with_defaults.authors).to eq([1, 5, 7])
|
383
|
+
end
|
384
|
+
|
385
|
+
it "allows callable default values" do
|
386
|
+
class_with_defaults = ClassWithDefaults.new
|
387
|
+
|
388
|
+
expect(class_with_defaults.callable).to eq("callable value")
|
389
|
+
end
|
390
|
+
|
391
|
+
it "doesn't use the same instance between multiple instances" do
|
392
|
+
class_with_defaults = ClassWithDefaults.new
|
393
|
+
class_with_defaults.authors << 2
|
394
|
+
|
395
|
+
class_with_defaults2 = ClassWithDefaults.new
|
396
|
+
|
397
|
+
expect(class_with_defaults2.authors).to eq([1, 2, 4])
|
398
|
+
end
|
399
|
+
end
|
367
400
|
end
|
data/spec/fixtures/classes.rb
CHANGED
@@ -113,3 +113,14 @@ class DefaultLenientAttributes
|
|
113
113
|
attribute :rate, :float
|
114
114
|
attribute :active, :boolean
|
115
115
|
end
|
116
|
+
|
117
|
+
class ClassWithDefaults
|
118
|
+
extend FastAttributes
|
119
|
+
|
120
|
+
define_attributes initialize: true, attributes: true do
|
121
|
+
attribute :title, String, default: "a title"
|
122
|
+
attribute :pages, Integer, default: 10
|
123
|
+
attribute :authors, Array, default: [1, 2, 4]
|
124
|
+
attribute :callable, String, default: lambda { "callable value" }
|
125
|
+
end
|
126
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kostiantyn Stepaniuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,6 +101,7 @@ files:
|
|
101
101
|
- fast_attributes.gemspec
|
102
102
|
- lib/fast_attributes.rb
|
103
103
|
- lib/fast_attributes/builder.rb
|
104
|
+
- lib/fast_attributes/default_attributes.rb
|
104
105
|
- lib/fast_attributes/type_cast.rb
|
105
106
|
- lib/fast_attributes/version.rb
|
106
107
|
- spec/fast_attributes/type_cast_spec.rb
|