fast_attributes 0.7.0 → 0.8.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.
- 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
|