attributes_dsl 0.0.1
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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +9 -0
- data/.metrics +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +20 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +16 -0
- data/Guardfile +14 -0
- data/LICENSE +21 -0
- data/README.md +209 -0
- data/Rakefile +39 -0
- data/attributes_dsl.gemspec +26 -0
- data/benchmark/run.rb +122 -0
- data/config/metrics/STYLEGUIDE +219 -0
- data/config/metrics/cane.yml +5 -0
- data/config/metrics/churn.yml +6 -0
- data/config/metrics/flay.yml +2 -0
- data/config/metrics/metric_fu.yml +14 -0
- data/config/metrics/reek.yml +1 -0
- data/config/metrics/roodi.yml +24 -0
- data/config/metrics/rubocop.yml +72 -0
- data/config/metrics/saikuro.yml +3 -0
- data/config/metrics/simplecov.yml +6 -0
- data/config/metrics/yardstick.yml +37 -0
- data/lib/attributes_dsl.rb +98 -0
- data/lib/attributes_dsl/attribute.rb +69 -0
- data/lib/attributes_dsl/attributes.rb +73 -0
- data/lib/attributes_dsl/version.rb +9 -0
- data/spec/integration/attributes_dsl_spec.rb +51 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/unit/attribute_spec.rb +126 -0
- data/spec/unit/attributes_spec.rb +76 -0
- metadata +138 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: da436a8b36ce35a3c4b4b87b33ed84a03a7dd910
|
4
|
+
data.tar.gz: 8d7edd3acf452eff9b4255a15a16cfee6f1d00d1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 63ea9addb5f796e1009f0140cc3523b4be461c280811d19b878edb3247ae5e1abe9f1cda60a05c703dfe7c28558bbf2868e2432c0b5957bce0d6ab15b0a8b408
|
7
|
+
data.tar.gz: e2555ba15ad33fbadbded4f29c0936687e23273ca534de57a9af3767a82f0a3372561d39c1145ec0031ca44f6afe4b0168d871173573c1b41b2f27ecc722fe74
|
data/.coveralls.yml
ADDED
data/.gitignore
ADDED
data/.metrics
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# Settings for metric_fu and its packages are collected in the `config/metrics`
|
2
|
+
# and loaded by the Hexx::Suit::Metrics::MetricFu.
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "hexx-suit"
|
6
|
+
Hexx::Suit::Metrics::MetricFu.load
|
7
|
+
rescue LoadError
|
8
|
+
puts "The 'hexx-suit' gem is not installed"
|
9
|
+
end
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
language: ruby
|
3
|
+
bundler_args: --without metrics --without benchmarks
|
4
|
+
cache: bundler
|
5
|
+
script: bundle exec rake test:coverage:run
|
6
|
+
rvm:
|
7
|
+
- '1.9.3'
|
8
|
+
- '2.0'
|
9
|
+
- '2.1'
|
10
|
+
- '2.2'
|
11
|
+
- ruby-head
|
12
|
+
- rbx-2 --1.9
|
13
|
+
- rbx-2 --2.1
|
14
|
+
- jruby-1.7-19mode
|
15
|
+
- jruby-9.0.0.0
|
16
|
+
- jruby-head
|
17
|
+
matrix:
|
18
|
+
allow_failures:
|
19
|
+
- rvm: ruby-head
|
20
|
+
- rvm: jruby-head
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
group :metrics do
|
6
|
+
gem "hexx-suit", "~> 2.3" if RUBY_ENGINE == "ruby" && RUBY_VERSION >= "2.1"
|
7
|
+
end
|
8
|
+
|
9
|
+
group :benchmarks do
|
10
|
+
gem "virtus"
|
11
|
+
gem "benchmark-ips"
|
12
|
+
gem "active_attr"
|
13
|
+
gem "fast_attributes"
|
14
|
+
gem "anima"
|
15
|
+
gem "kwattr"
|
16
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
4
|
+
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
|
7
|
+
watch(%r{^lib/attributes_dsl/(.+)\.rb}) do |m|
|
8
|
+
"spec/unit/#{m[1]}_spec.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
watch("lib/attributes_dsl.rb") { "spec" }
|
12
|
+
watch("spec/spec_helper.rb") { "spec" }
|
13
|
+
|
14
|
+
end # guard :rspec
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2015 Andrew Kozin (nepalez), andrew.kozin@gmail.com
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,209 @@
|
|
1
|
+
Attributes DSL
|
2
|
+
==============
|
3
|
+
|
4
|
+
[][gem]
|
5
|
+
[][travis]
|
6
|
+
[][gemnasium]
|
7
|
+
[][codeclimate]
|
8
|
+
[][coveralls]
|
9
|
+
[][inch]
|
10
|
+
|
11
|
+
Lightweight DSL to define PORO attributes.
|
12
|
+
|
13
|
+
Uses immutable (deeply frozen) instances via [ice_nine][ice_nine] gem.
|
14
|
+
|
15
|
+
Synopsis
|
16
|
+
--------
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
require "attributes_dsl"
|
20
|
+
|
21
|
+
class User
|
22
|
+
extend AttributesDSL
|
23
|
+
|
24
|
+
# `name` is required should be symbolized
|
25
|
+
attribute :name, required: true do |value|
|
26
|
+
value.to_s.to_sym
|
27
|
+
end
|
28
|
+
|
29
|
+
# `sex` is optional and set to `:male` by default.
|
30
|
+
# It can be set to either :male or :female
|
31
|
+
attribute :sex, default: :male do |value|
|
32
|
+
(value == :male )? :male : :female
|
33
|
+
end
|
34
|
+
|
35
|
+
# `age` is optional and set to `nil` by default.
|
36
|
+
# Then it is converted to integer
|
37
|
+
attribute :age, &:to_i
|
38
|
+
|
39
|
+
# `position` is optional and set to `nil` by default
|
40
|
+
attribute :position
|
41
|
+
|
42
|
+
# All other attributes are ignored
|
43
|
+
end
|
44
|
+
|
45
|
+
user = User.new(name: "Jane", sex: :women, age: "26", place: "Moscow")
|
46
|
+
user.attributes
|
47
|
+
# => { name: :Jane, sex: :female, age: 26, position: nil }
|
48
|
+
|
49
|
+
# Aliases for attributes[:some_attribute]
|
50
|
+
user.name # => :Jane
|
51
|
+
user.sex # => :female
|
52
|
+
user.age # => 26
|
53
|
+
user.position # => nil
|
54
|
+
|
55
|
+
# Required attributes should be assigned:
|
56
|
+
user = User.new(sex: :women, age: "26", place: "Moscow")
|
57
|
+
# => #<ArgumentError "Undefined attributes: name">
|
58
|
+
```
|
59
|
+
|
60
|
+
Additional Details
|
61
|
+
------------------
|
62
|
+
|
63
|
+
The `attribute` class method takes the `name` and 2 options:
|
64
|
+
- `:default` for the default value (otherwise `nil`);
|
65
|
+
- `:required` to declare the attribute as required. It will be ignored if a default value is provided!
|
66
|
+
|
67
|
+
It is also takes the block, used to coerce a value. The coercer is applied to the default value too.
|
68
|
+
|
69
|
+
Also notice, that instance methods (like `#name`) are just aliases for the corresponding value of the `#attributes` hash. Instance variables aren't defined for them (to ensure syncronization between `#name` and `#attributes[:name]`):
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
user = User.new(name: "John")
|
73
|
+
user.attributes # => { name: :John, sex: :male, age: 0, position: nil }
|
74
|
+
user.name # => :John
|
75
|
+
|
76
|
+
# but
|
77
|
+
user.instance_variable_get :@name # => nil
|
78
|
+
```
|
79
|
+
|
80
|
+
You're free to redefine attributes (class settings are used by the initializer only):
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
user.attributes[:name] = "Jim"
|
84
|
+
user.attributes # => { name: "Jim", sex: :male, age: 0, position: nil }
|
85
|
+
user.name # => "Jim"
|
86
|
+
```
|
87
|
+
|
88
|
+
But if you (like me) prefer instance immutability, you can deeply freeze instances safely:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
require "ice_nine"
|
92
|
+
|
93
|
+
class User
|
94
|
+
# ... staff like before
|
95
|
+
|
96
|
+
def initializer(attributes)
|
97
|
+
super
|
98
|
+
IceNine.deep_freeze(self)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
args = { user: "Joe" }
|
103
|
+
|
104
|
+
user = User.new(args)
|
105
|
+
user.frozen? # => true
|
106
|
+
user.attributes.frozen? # => true
|
107
|
+
|
108
|
+
# "Safely" means:
|
109
|
+
args.frozen? # => false
|
110
|
+
```
|
111
|
+
|
112
|
+
Freezing instances to exclude side effects is a part of my coding style. That's why the gem doesn't (and won't do) care about changing attributes after initialization.
|
113
|
+
|
114
|
+
Benchmarks
|
115
|
+
----------
|
116
|
+
|
117
|
+
The list of gems to compare has been taken from [Idiosyncratic Ruby #18][idiosyncratic_ruby] by Jan Lelis. I've selected only those gems that support initialization from hash.
|
118
|
+
|
119
|
+
Look at the [benchmark source][benchmark] for details.
|
120
|
+
|
121
|
+
The results are following:
|
122
|
+
|
123
|
+
```
|
124
|
+
-------------------------------------------------
|
125
|
+
anima 202.863k (± 5.1%) i/s - 1.023M
|
126
|
+
kwattr 171.461k (± 5.3%) i/s - 855.680k
|
127
|
+
fast_attributes 156.596k (± 2.5%) i/s - 785.792k
|
128
|
+
attributes_dsl 58.966k (± 4.6%) i/s - 296.514k
|
129
|
+
active_attr 58.322k (± 2.8%) i/s - 293.205k
|
130
|
+
virtus 45.734k (± 2.7%) i/s - 228.960k
|
131
|
+
|
132
|
+
Comparison:
|
133
|
+
anima: 202862.9 i/s
|
134
|
+
kwattr: 171460.9 i/s - 1.18x slower
|
135
|
+
fast_attributes: 156596.3 i/s - 1.30x slower
|
136
|
+
attributes_dsl: 58966.5 i/s - 3.44x slower
|
137
|
+
active_attr: 58321.6 i/s - 3.48x slower
|
138
|
+
virtus: 45734.3 i/s - 4.44x slower
|
139
|
+
```
|
140
|
+
|
141
|
+
Results above are pretty reasonable.
|
142
|
+
|
143
|
+
The gem is faster than `virtus` that has many additional features.
|
144
|
+
|
145
|
+
It is as fast as `active_attrs` (but has more customizable coercers).
|
146
|
+
|
147
|
+
It is 2 times slower than `fast_attributes` that has no coercer and default values. And it is 3-3.5 times slower than `anima` and `kwattr` that provides only the base settings.
|
148
|
+
|
149
|
+
Installation
|
150
|
+
------------
|
151
|
+
|
152
|
+
Add this line to your application's Gemfile:
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
# Gemfile
|
156
|
+
gem "attributes_dsl"
|
157
|
+
```
|
158
|
+
|
159
|
+
Then execute:
|
160
|
+
|
161
|
+
```
|
162
|
+
bundle
|
163
|
+
```
|
164
|
+
|
165
|
+
Or add it manually:
|
166
|
+
|
167
|
+
```
|
168
|
+
gem install attributes_dsl
|
169
|
+
```
|
170
|
+
|
171
|
+
Compatibility
|
172
|
+
-------------
|
173
|
+
|
174
|
+
Tested under rubies [compatible to MRI 1.9+][versions].
|
175
|
+
|
176
|
+
Uses [RSpec][rspec] 3.0+ for testing and [hexx-suit][hexx-suit] for dev/test tools collection.
|
177
|
+
|
178
|
+
100% [mutant]-proof covered.
|
179
|
+
|
180
|
+
Contributing
|
181
|
+
------------
|
182
|
+
|
183
|
+
* Read the [STYLEGUIDE](config/metrics/STYLEGUIDE)
|
184
|
+
* [Fork the project](https://github.com/nepalez/attributes_dsl)
|
185
|
+
* Create your feature branch (`git checkout -b my-new-feature`)
|
186
|
+
* Add tests for it
|
187
|
+
* Run `rake mutant` or `rake exhort` to ensure 100% [mutant][mutant] coverage
|
188
|
+
* Commit your changes (`git commit -am '[UPDATE] Add some feature'`)
|
189
|
+
* Push to the branch (`git push origin my-new-feature`)
|
190
|
+
* Create a new Pull Request
|
191
|
+
|
192
|
+
License
|
193
|
+
-------
|
194
|
+
|
195
|
+
See the [MIT LICENSE](LICENSE).
|
196
|
+
|
197
|
+
[codeclimate]: https://codeclimate.com/github/nepalez/attributes_dsl
|
198
|
+
[coveralls]: https://coveralls.io/r/nepalez/attributes_dsl
|
199
|
+
[gem]: https://rubygems.org/gems/attributes_dsl
|
200
|
+
[gemnasium]: https://gemnasium.com/nepalez/attributes_dsl
|
201
|
+
[travis]: https://travis-ci.org/nepalez/attributes_dsl
|
202
|
+
[inch]: https://inch-ci.org/github/nepalez/attributes_dsl
|
203
|
+
[versions]: .travis.yml
|
204
|
+
[rspec]: http://rspec.org
|
205
|
+
[hexx-suit]: https://github.com/hexx-rb/hexx-suit
|
206
|
+
[mutant]: https://github.com/mbj/mutant
|
207
|
+
[ice_nine]: https://github.com/dkubb/ice_nine
|
208
|
+
[idiosyncratic_ruby]: http://idiosyncratic-ruby.com/18-con-struct-attributes.html
|
209
|
+
[benchmark]: benchmark/run.rb
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "rubygems"
|
5
|
+
|
6
|
+
# Loads bundler tasks
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
# Loads the Hexx::RSpec and its tasks
|
10
|
+
begin
|
11
|
+
require "hexx-suit"
|
12
|
+
Hexx::Suit.install_tasks
|
13
|
+
rescue LoadError
|
14
|
+
require "hexx-rspec"
|
15
|
+
Hexx::RSpec.install_tasks
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Sets the Hexx::RSpec :test task to default"
|
19
|
+
task :default do
|
20
|
+
system "bundle exec rake test:coverage:run"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Runs mutation metric for testing"
|
24
|
+
task :mutant do
|
25
|
+
system "mutant -r ./spec/spec_helper --use rspec AttributesDSL* --fail-fast"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Exhort all evils"
|
29
|
+
task :exhort do
|
30
|
+
system "mutant -r ./spec/spec_helper --use rspec AttributesDSL*"
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Runs all the necessary metrics before making a commit"
|
34
|
+
task prepare: %w(exhort check:inch check:rubocop check:fu)
|
35
|
+
|
36
|
+
desc "Runs benchmarks"
|
37
|
+
task :benchmark do
|
38
|
+
system "ruby benchmark/run.rb"
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "attributes_dsl/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
|
6
|
+
gem.name = "attributes_dsl"
|
7
|
+
gem.version = AttributesDSL::VERSION.dup
|
8
|
+
gem.author = "Andrew Kozin"
|
9
|
+
gem.email = "andrew.kozin@gmail.com"
|
10
|
+
gem.homepage = "https://github.com/nepalez/attributes_dsl"
|
11
|
+
gem.summary = "Lightweight DSL to define PORO attributes"
|
12
|
+
gem.license = "MIT"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
15
|
+
gem.test_files = Dir["spec/**/*.rb"]
|
16
|
+
gem.extra_rdoc_files = Dir["README.md", "LICENSE"]
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
gem.required_ruby_version = ">= 1.9.3"
|
20
|
+
|
21
|
+
gem.add_runtime_dependency "ice_nine", "~> 0.11"
|
22
|
+
gem.add_runtime_dependency "equalizer", "~> 0.0", ">= 0.0.11"
|
23
|
+
|
24
|
+
gem.add_development_dependency "hexx-rspec", "~> 0.5", ">= 0.5.2"
|
25
|
+
|
26
|
+
end # Gem::Specification
|
data/benchmark/run.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require "benchmark/ips"
|
2
|
+
|
3
|
+
module AttributesDSLExample
|
4
|
+
require "attributes_dsl"
|
5
|
+
|
6
|
+
class User
|
7
|
+
extend AttributesDSL
|
8
|
+
|
9
|
+
attribute :foo, required: true, &:to_s
|
10
|
+
attribute :bar, default: :BAR, &:to_s
|
11
|
+
attribute :baz, default: :BAZ, &:to_s
|
12
|
+
attribute :qux, &:to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.call
|
16
|
+
User.new(foo: :FOO, bar: :BAR, baz: :BAZ, qux: :QUX)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module VirtusExample
|
21
|
+
require "virtus"
|
22
|
+
|
23
|
+
class User
|
24
|
+
include Virtus.model
|
25
|
+
|
26
|
+
attribute :foo, String, required: true
|
27
|
+
attribute :bar, String, default: :BAR
|
28
|
+
attribute :baz, String, default: :BAZ
|
29
|
+
attribute :qux, String
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.call
|
33
|
+
User.new(foo: :FOO, bar: :BAR, baz: :BAZ, qux: :QUX)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module ActiveAttrExample
|
38
|
+
require "active_attr"
|
39
|
+
|
40
|
+
class User
|
41
|
+
include ActiveAttr::MassAssignment
|
42
|
+
attr_accessor :foo, :bar, :baz, :qux
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.call
|
46
|
+
User.new(foo: :FOO, bar: :BAR, baz: :BAZ, qux: :QUX)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module FastAttributesExample
|
51
|
+
require "fast_attributes"
|
52
|
+
|
53
|
+
class User
|
54
|
+
extend FastAttributes
|
55
|
+
|
56
|
+
define_attributes initialize: true do
|
57
|
+
attribute :foo, String
|
58
|
+
attribute :bar, String
|
59
|
+
attribute :baz, String
|
60
|
+
attribute :qux, String
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.call
|
65
|
+
User.new(foo: :FOO, bar: :BAR, baz: :BAZ, qux: :QUX)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module AnimaExample
|
70
|
+
require "anima"
|
71
|
+
|
72
|
+
class User
|
73
|
+
include Anima.new(:foo, :bar, :baz, :qux)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.call
|
77
|
+
User.new(foo: :FOO, bar: :BAR, baz: :BAZ, qux: :QUX)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
module KwattrExample
|
82
|
+
require "kwattr"
|
83
|
+
|
84
|
+
class User
|
85
|
+
kwattr :foo, :bar, :baz, :qux
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.call
|
89
|
+
User.new(foo: :FOO, bar: :BAR, baz: :BAZ, qux: :QUX)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Provide a benchmark
|
94
|
+
Benchmark.ips do |x|
|
95
|
+
x.config time: 5, warmup: 5
|
96
|
+
|
97
|
+
x.report("attributes_dsl") do
|
98
|
+
AttributesDSLExample.call
|
99
|
+
end
|
100
|
+
|
101
|
+
x.report("virtus") do
|
102
|
+
VirtusExample.call
|
103
|
+
end
|
104
|
+
|
105
|
+
x.report("active_attr") do
|
106
|
+
AttributesDSLExample.call
|
107
|
+
end
|
108
|
+
|
109
|
+
x.report("fast_attributes") do
|
110
|
+
FastAttributesExample.call
|
111
|
+
end
|
112
|
+
|
113
|
+
x.report("anima") do
|
114
|
+
AnimaExample.call
|
115
|
+
end
|
116
|
+
|
117
|
+
x.report("kwattr") do
|
118
|
+
KwattrExample.call
|
119
|
+
end
|
120
|
+
|
121
|
+
x.compare!
|
122
|
+
end
|