attrio 0.5.0 → 0.6.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 +7 -0
- data/README.md +18 -0
- data/lib/attrio.rb +24 -15
- data/lib/attrio/attribute.rb +15 -1
- data/lib/attrio/attributes_parser.rb +6 -8
- data/lib/attrio/builders/accessor_builder.rb +1 -1
- data/lib/attrio/builders/reader_builder.rb +4 -4
- data/lib/attrio/default_value.rb +1 -1
- data/lib/attrio/default_value/callable.rb +1 -1
- data/lib/attrio/default_value/clonable.rb +2 -2
- data/lib/attrio/default_value/symbol.rb +2 -2
- data/lib/attrio/initialize.rb +12 -13
- data/lib/attrio/inspect.rb +22 -20
- data/lib/attrio/reset.rb +16 -15
- data/lib/attrio/version.rb +1 -1
- data/spec/integration/embedded_value_spec.rb +1 -1
- data/spec/unit/inspect_spec.rb +0 -21
- data/spec/unit/reset_spec.rb +2 -2
- metadata +17 -37
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 861576afb99f94868a01b939116bfba6d6276306
|
4
|
+
data.tar.gz: 6a111a94772edb9199b59b095002dfac0f03d88d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b064f63381b115945464627375774ae37267d965997474af9512eb704d5ba6c4a3028bea7abcce388564f3eb689a08d92e531eb24d0157bd436f7f053010f93a
|
7
|
+
data.tar.gz: 7f907cc9f4db1869b55c8e7d7c1b957d3ef63377905f63f33d9ac99bfc7773dbea8e6a683e67a02f8f0595c73cba8d40acce26bfe71724151088e09a7a5129ca
|
data/README.md
CHANGED
@@ -77,6 +77,11 @@ class User
|
|
77
77
|
attr :age, Integer
|
78
78
|
attr :birthday, DateTime
|
79
79
|
end
|
80
|
+
|
81
|
+
define_attributes :as => 'settings' do
|
82
|
+
attr :receives_notifications, Boolean, :default => true
|
83
|
+
end
|
84
|
+
|
80
85
|
end
|
81
86
|
```
|
82
87
|
|
@@ -129,6 +134,19 @@ class Page
|
|
129
134
|
end
|
130
135
|
```
|
131
136
|
|
137
|
+
You can does your attribute still has default value or not.
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
p = Page.new
|
141
|
+
=> #<Page title: nil, views: 0, published: false, slug: nil, editor_title: "UNPUBLISHED">
|
142
|
+
p.attributes[:editor_title].default?
|
143
|
+
=> true
|
144
|
+
p.editor_title = 'PUBLISHED'
|
145
|
+
=> "PUBLISHED"
|
146
|
+
p.attributes[:editor_title].default?
|
147
|
+
=> false
|
148
|
+
```
|
149
|
+
|
132
150
|
### Embed Value
|
133
151
|
You can embed values in Attrio just like you do it in Virtus.
|
134
152
|
|
data/lib/attrio.rb
CHANGED
@@ -13,44 +13,53 @@ module Attrio
|
|
13
13
|
autoload :Helpers, 'attrio/helpers'
|
14
14
|
|
15
15
|
def self.included(base)
|
16
|
-
base.send :include, Attrio::Initialize
|
17
|
-
base.send :include, Attrio::Inspect
|
18
16
|
base.send :include, Attrio::Reset
|
17
|
+
base.send :include, Attrio::Inspect
|
19
18
|
|
19
|
+
base.send :extend, Attrio::Initialize
|
20
20
|
base.send :extend, Attrio::ClassMethods
|
21
21
|
end
|
22
22
|
|
23
23
|
module ClassMethods
|
24
|
+
def attrio
|
25
|
+
@attrio ||= {}
|
26
|
+
end
|
27
|
+
|
24
28
|
def define_attributes(options = {}, &block)
|
25
|
-
options
|
29
|
+
as = options.delete(:as) || :attributes
|
30
|
+
self.attrio[as] = options
|
26
31
|
|
27
32
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
28
|
-
@#{
|
33
|
+
@#{as} ||= {}
|
29
34
|
|
30
35
|
class << self
|
31
|
-
def #{
|
36
|
+
def #{as}(attributes = [])
|
32
37
|
attributes = Helpers.to_a(attributes).flatten
|
33
|
-
return @#{
|
38
|
+
return @#{as} if attributes.empty?
|
34
39
|
|
35
|
-
attributes = @#{
|
36
|
-
@#{
|
40
|
+
attributes = @#{as}.keys & attributes
|
41
|
+
@#{as}.select{ |k,v| attributes.include?(k) }
|
37
42
|
end
|
38
43
|
|
39
44
|
def inherited(subclass)
|
40
|
-
subclass.instance_variable_set("@#{
|
45
|
+
subclass.instance_variable_set("@#{as}", instance_variable_get("@#{as}").dup)
|
41
46
|
end
|
42
47
|
end
|
43
48
|
|
44
|
-
def #{
|
45
|
-
self.class.#{
|
49
|
+
def #{as}(attributes = [])
|
50
|
+
# self.class.#{as}(attributes)
|
51
|
+
|
52
|
+
attributes = Helpers.to_a(attributes).flatten
|
53
|
+
return @#{as} if attributes.empty?
|
54
|
+
|
55
|
+
attributes = @#{as}.keys & attributes
|
56
|
+
@#{as}.select{ |k,v| attributes.include?(k) }
|
46
57
|
end
|
47
58
|
EOS
|
48
59
|
|
49
|
-
self.
|
50
|
-
self.define_attrio_reset(options[:as])
|
51
|
-
self.define_attrio_inspect(options[:as]) unless options[:inspect] == false
|
60
|
+
self.define_attrio_reset(as)
|
52
61
|
|
53
|
-
Attrio::AttributesParser.new(self,
|
62
|
+
Attrio::AttributesParser.new(self, as, &block)
|
54
63
|
end
|
55
64
|
|
56
65
|
def const_missing(name)
|
data/lib/attrio/attribute.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Attrio
|
4
4
|
class Attribute
|
5
|
-
attr_reader :name, :type, :options
|
5
|
+
attr_reader :name, :type, :options, :object
|
6
6
|
|
7
7
|
def initialize(name, type, options)
|
8
8
|
@name = name; @type = type; @options = Helpers.symbolize_hash_keys(options)
|
@@ -35,6 +35,20 @@ module Attrio
|
|
35
35
|
@default_value
|
36
36
|
end
|
37
37
|
|
38
|
+
def reset!
|
39
|
+
raise ArgumentError if self.object.nil?
|
40
|
+
|
41
|
+
value = self.default_value.is_a?(Attrio::DefaultValue::Base) ? self.default_value.call(self.object) : self.default_value
|
42
|
+
self.object.send(self.writer_method_name, value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def default?
|
46
|
+
raise ArgumentError if self.object.nil?
|
47
|
+
|
48
|
+
value = self.default_value.is_a?(Attrio::DefaultValue::Base) ? self.default_value.call(self.object) : self.default_value
|
49
|
+
self.object.send(self.reader_method_name) == value
|
50
|
+
end
|
51
|
+
|
38
52
|
def define_writer(klass)
|
39
53
|
Attrio::Builders::WriterBuilder.define(klass, self.type,
|
40
54
|
self.options.merge({
|
@@ -2,13 +2,11 @@
|
|
2
2
|
|
3
3
|
module Attrio
|
4
4
|
class AttributesParser
|
5
|
-
attr_reader :klass, :
|
5
|
+
attr_reader :klass, :as
|
6
6
|
|
7
|
-
def initialize(klass,
|
7
|
+
def initialize(klass, as, &block)
|
8
8
|
@klass = klass
|
9
|
-
@
|
10
|
-
|
11
|
-
raise ArgumentError.new('Missing options[:as] value' ) if @options[:as].blank?
|
9
|
+
@as = as
|
12
10
|
|
13
11
|
self.instance_eval(&block)
|
14
12
|
end
|
@@ -47,9 +45,9 @@ module Attrio
|
|
47
45
|
|
48
46
|
protected
|
49
47
|
|
50
|
-
def as
|
51
|
-
|
52
|
-
end
|
48
|
+
# def as
|
49
|
+
# self.options[:as]
|
50
|
+
# end
|
53
51
|
|
54
52
|
def fetch_type(name)
|
55
53
|
return if name.nil?
|
@@ -11,13 +11,13 @@ module Attrio
|
|
11
11
|
|
12
12
|
def self.define_accessor(klass, type, options)
|
13
13
|
unless klass.method_defined?(options[:method_name])
|
14
|
-
klass.send :define_method, options[:method_name] do
|
14
|
+
klass.send :define_method, options[:method_name] do
|
15
15
|
self.instance_variable_get(options[:instance_variable_name])
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
klass.send options[:method_visibility], options[:method_name]
|
19
|
-
end
|
20
|
-
end
|
19
|
+
end
|
20
|
+
end
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/lib/attrio/default_value.rb
CHANGED
@@ -13,10 +13,10 @@ module Attrio
|
|
13
13
|
# Symbol value is returned if the object doesn't respond to value
|
14
14
|
#
|
15
15
|
# @param [Object] instance
|
16
|
-
#
|
16
|
+
#
|
17
17
|
def call(instance)
|
18
18
|
instance.respond_to?(self.value, true) ? instance.send(self.value) : self.value
|
19
|
-
end
|
19
|
+
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
data/lib/attrio/initialize.rb
CHANGED
@@ -2,21 +2,20 @@
|
|
2
2
|
|
3
3
|
module Attrio
|
4
4
|
module Initialize
|
5
|
-
def
|
6
|
-
|
7
|
-
end
|
5
|
+
def new(*args, &block)
|
6
|
+
obj = self.allocate
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
obj
|
17
|
-
end
|
18
|
-
EOS
|
8
|
+
obj.class.attrio.each do |group, options|
|
9
|
+
obj.instance_variable_set("@#{group}", {})
|
10
|
+
obj.class.send("#{group}").each do |name, attribute|
|
11
|
+
obj.send("#{group}")[name] = attribute.dup
|
12
|
+
obj.send("#{group}")[name].instance_variable_set(:@object, obj)
|
13
|
+
obj.send("#{group}")[name].reset!
|
14
|
+
end
|
19
15
|
end
|
16
|
+
|
17
|
+
obj.send :initialize, *args, &block
|
18
|
+
obj
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
data/lib/attrio/inspect.rb
CHANGED
@@ -2,31 +2,33 @@
|
|
2
2
|
|
3
3
|
module Attrio
|
4
4
|
module Inspect
|
5
|
-
def
|
6
|
-
|
7
|
-
end
|
5
|
+
def inspect
|
6
|
+
inspection = []
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
inspection = self.send(as.to_s).map { |key, attribute|
|
8
|
+
self.class.attrio.each do |group, options|
|
9
|
+
unless options[:inspect] == false
|
10
|
+
inspection << self.send(group).map { |key, attribute|
|
13
11
|
self.inspect_attribute(key, attribute.instance_variable_name)
|
14
|
-
}
|
15
|
-
|
16
|
-
"#<#{self.class} #{inspection}>"
|
12
|
+
}
|
17
13
|
end
|
14
|
+
end
|
18
15
|
|
19
|
-
|
20
|
-
|
16
|
+
unless inspection.size == 0
|
17
|
+
"#<#{self.class} #{inspection.flatten.compact.join(', ')}>"
|
18
|
+
else
|
19
|
+
super
|
20
|
+
end
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
def inspect_attribute(attribute_name, instance_variable_name)
|
24
|
+
value = instance_variable_get(instance_variable_name.to_s)
|
25
|
+
|
26
|
+
if value.is_a?(String) && value.length > 50
|
27
|
+
"#{attribute_name.to_s}[#{value.size}]: " + "#{value[0..50]}...".inspect
|
28
|
+
elsif value.is_a?(Array) && value.length > 5
|
29
|
+
"#{attribute_name.to_s}[#{value.size}]: " + "#{value[0..5]}...".inspect
|
30
|
+
else
|
31
|
+
"#{attribute_name.to_s}: " + value.inspect
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
data/lib/attrio/reset.rb
CHANGED
@@ -8,24 +8,25 @@ module Attrio
|
|
8
8
|
|
9
9
|
module ClassMethods
|
10
10
|
def define_attrio_reset(as)
|
11
|
-
define_method "reset_#{as.to_s}" do |attributes = []|
|
12
|
-
self.send(as.to_s, attributes).values.each{ |attribute| self.send(attribute.writer_method_name, nil) }
|
13
|
-
self.send("set_#{as.to_s}_defaults", attributes)
|
14
|
-
|
15
|
-
|
16
|
-
define_method "reset_#{as.to_s}_defaults" do |attributes = []|
|
17
|
-
self.send(as.to_s, attributes).values.select{ |attribute| !attribute.default_value.nil? }.each { |attribute| self.send(attribute.writer_method_name, nil) }
|
18
|
-
self.send("set_#{as.to_s}_defaults", attributes)
|
11
|
+
define_method "reset_#{as.to_s}" do |attributes = []|
|
12
|
+
# self.send(as.to_s, attributes).values.each{ |attribute| self.send(attribute.writer_method_name, nil) }
|
13
|
+
# self.send("set_#{as.to_s}_defaults", attributes)
|
14
|
+
self.send(as.to_s, attributes).values.each{ |attribute| attribute.reset! }
|
19
15
|
end
|
20
16
|
|
21
|
-
define_method "
|
22
|
-
|
23
|
-
|
17
|
+
# define_method "reset_#{as.to_s}_defaults" do |attributes = []|
|
18
|
+
# self.send(as.to_s, attributes).values.select{ |attribute| !attribute.default_value.nil? }.each { |attribute| self.send(attribute.writer_method_name, nil) }
|
19
|
+
# self.send("set_#{as.to_s}_defaults", attributes)
|
20
|
+
# end
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
# define_method "set_#{as.to_s}_defaults" do |attributes = []|
|
23
|
+
# self.send(as.to_s, attributes).values.select{ |attribute| !attribute.default_value.nil? }.each do |attribute|
|
24
|
+
# next if self.send(attribute.reader_method_name).present?
|
25
|
+
|
26
|
+
# default_value = attribute.default_value.is_a?(Attrio::DefaultValue::Base) ? attribute.default_value.call(self) : attribute.default_value
|
27
|
+
# self.send(attribute.writer_method_name, default_value)
|
28
|
+
# end
|
29
|
+
# end
|
29
30
|
end
|
30
31
|
end
|
31
32
|
end
|
data/lib/attrio/version.rb
CHANGED
data/spec/unit/inspect_spec.rb
CHANGED
@@ -17,25 +17,4 @@ describe Attrio::Inspect do
|
|
17
17
|
object.method(:inspect).source_location.first.should match(/lib\/attrio\/inspect.rb/)
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
21
|
-
context ':inspect option passed' do
|
22
|
-
let(:model) do
|
23
|
-
Class.new do
|
24
|
-
include Attrio
|
25
|
-
|
26
|
-
define_attributes :inspect => false do
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
let(:object) { model.new }
|
32
|
-
|
33
|
-
it 'should not have inspect defined by attrio' do
|
34
|
-
if RUBY_ENGINE == 'rbx'
|
35
|
-
object.method(:inspect).source_location.first.should_not match(/attrio/)
|
36
|
-
else
|
37
|
-
object.method(:inspect).source_location.should be_nil
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
20
|
end
|
data/spec/unit/reset_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe Attrio::Reset do
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
let(:object) do
|
15
|
+
let(:object) do
|
16
16
|
obj = model.new
|
17
17
|
obj.first = 'first'
|
18
18
|
obj.second = 'second'
|
@@ -20,7 +20,7 @@ describe Attrio::Reset do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'should respond_to reset_attributes' do
|
23
|
-
object.respond_to?(:reset_attributes).should be_true
|
23
|
+
object.respond_to?(:reset_attributes).should be_true
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should reset attributes without :default option to nil' do
|
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attrio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.6.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Igor Alexandrov
|
@@ -10,28 +9,25 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date: 2013-
|
12
|
+
date: 2013-08-26 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: rspec
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
17
|
requirements:
|
20
|
-
- -
|
18
|
+
- - '>='
|
21
19
|
- !ruby/object:Gem::Version
|
22
20
|
version: '0'
|
23
21
|
type: :development
|
24
22
|
prerelease: false
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
24
|
requirements:
|
28
|
-
- -
|
25
|
+
- - '>='
|
29
26
|
- !ruby/object:Gem::Version
|
30
27
|
version: '0'
|
31
28
|
- !ruby/object:Gem::Dependency
|
32
29
|
name: webmock
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
31
|
requirements:
|
36
32
|
- - ~>
|
37
33
|
- !ruby/object:Gem::Version
|
@@ -39,7 +35,6 @@ dependencies:
|
|
39
35
|
type: :development
|
40
36
|
prerelease: false
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
38
|
requirements:
|
44
39
|
- - ~>
|
45
40
|
- !ruby/object:Gem::Version
|
@@ -47,65 +42,57 @@ dependencies:
|
|
47
42
|
- !ruby/object:Gem::Dependency
|
48
43
|
name: simplecov
|
49
44
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
45
|
requirements:
|
52
|
-
- -
|
46
|
+
- - '>='
|
53
47
|
- !ruby/object:Gem::Version
|
54
48
|
version: '0'
|
55
49
|
type: :development
|
56
50
|
prerelease: false
|
57
51
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
52
|
requirements:
|
60
|
-
- -
|
53
|
+
- - '>='
|
61
54
|
- !ruby/object:Gem::Version
|
62
55
|
version: '0'
|
63
56
|
- !ruby/object:Gem::Dependency
|
64
57
|
name: coveralls
|
65
58
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
59
|
requirements:
|
68
|
-
- -
|
60
|
+
- - '>='
|
69
61
|
- !ruby/object:Gem::Version
|
70
62
|
version: '0'
|
71
63
|
type: :development
|
72
64
|
prerelease: false
|
73
65
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
66
|
requirements:
|
76
|
-
- -
|
67
|
+
- - '>='
|
77
68
|
- !ruby/object:Gem::Version
|
78
69
|
version: '0'
|
79
70
|
- !ruby/object:Gem::Dependency
|
80
71
|
name: rake
|
81
72
|
requirement: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
73
|
requirements:
|
84
|
-
- -
|
74
|
+
- - '>='
|
85
75
|
- !ruby/object:Gem::Version
|
86
76
|
version: '0'
|
87
77
|
type: :development
|
88
78
|
prerelease: false
|
89
79
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
80
|
requirements:
|
92
|
-
- -
|
81
|
+
- - '>='
|
93
82
|
- !ruby/object:Gem::Version
|
94
83
|
version: '0'
|
95
84
|
- !ruby/object:Gem::Dependency
|
96
85
|
name: bundler
|
97
86
|
requirement: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
87
|
requirements:
|
100
|
-
- -
|
88
|
+
- - '>='
|
101
89
|
- !ruby/object:Gem::Version
|
102
90
|
version: '0'
|
103
91
|
type: :development
|
104
92
|
prerelease: false
|
105
93
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
94
|
requirements:
|
108
|
-
- -
|
95
|
+
- - '>='
|
109
96
|
- !ruby/object:Gem::Version
|
110
97
|
version: '0'
|
111
98
|
description:
|
@@ -171,33 +158,26 @@ files:
|
|
171
158
|
- spec/unit/types/time_spec.rb
|
172
159
|
homepage: https://github.com/jetrockets/attrio
|
173
160
|
licenses: []
|
161
|
+
metadata: {}
|
174
162
|
post_install_message:
|
175
163
|
rdoc_options: []
|
176
164
|
require_paths:
|
177
165
|
- lib
|
178
166
|
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
-
none: false
|
180
167
|
requirements:
|
181
|
-
- -
|
168
|
+
- - '>='
|
182
169
|
- !ruby/object:Gem::Version
|
183
170
|
version: '0'
|
184
|
-
segments:
|
185
|
-
- 0
|
186
|
-
hash: -10874694009707771
|
187
171
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
|
-
none: false
|
189
172
|
requirements:
|
190
|
-
- -
|
173
|
+
- - '>='
|
191
174
|
- !ruby/object:Gem::Version
|
192
175
|
version: '0'
|
193
|
-
segments:
|
194
|
-
- 0
|
195
|
-
hash: -10874694009707771
|
196
176
|
requirements: []
|
197
177
|
rubyforge_project:
|
198
|
-
rubygems_version:
|
178
|
+
rubygems_version: 2.0.3
|
199
179
|
signing_key:
|
200
|
-
specification_version:
|
180
|
+
specification_version: 4
|
201
181
|
summary: Attributes for plain old Ruby objects. No dependencies, only simplicity and
|
202
182
|
clearness.
|
203
183
|
test_files:
|