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.
@@ -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
 
@@ -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[:as] ||= :attributes
29
+ as = options.delete(:as) || :attributes
30
+ self.attrio[as] = options
26
31
 
27
32
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
28
- @#{options[:as]} ||= {}
33
+ @#{as} ||= {}
29
34
 
30
35
  class << self
31
- def #{options[:as]}(attributes = [])
36
+ def #{as}(attributes = [])
32
37
  attributes = Helpers.to_a(attributes).flatten
33
- return @#{options[:as]} if attributes.empty?
38
+ return @#{as} if attributes.empty?
34
39
 
35
- attributes = @#{options[:as]}.keys & attributes
36
- @#{options[:as]}.select{ |k,v| attributes.include?(k) }
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("@#{options[:as]}", instance_variable_get("@#{options[:as]}").dup)
45
+ subclass.instance_variable_set("@#{as}", instance_variable_get("@#{as}").dup)
41
46
  end
42
47
  end
43
48
 
44
- def #{options[:as]}(attributes = [])
45
- self.class.#{options[:as]}(attributes)
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.define_attrio_new(options[:as])
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, options, &block)
62
+ Attrio::AttributesParser.new(self, as, &block)
54
63
  end
55
64
 
56
65
  def const_missing(name)
@@ -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, :options
5
+ attr_reader :klass, :as
6
6
 
7
- def initialize(klass, options, &block)
7
+ def initialize(klass, as, &block)
8
8
  @klass = klass
9
- @options = options
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
- self.options[:as]
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?
@@ -17,7 +17,7 @@ module Attrio
17
17
  type.send("default_#{self.accessor.to_s}_aliases", options[:method_name]).each do |alias_method_name|
18
18
  klass.send(:alias_method, alias_method_name, options[:method_name])
19
19
  end
20
- end
20
+ end
21
21
  end
22
22
  end
23
23
  end
@@ -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
@@ -7,7 +7,7 @@ module Attrio
7
7
  autoload :Clonable, 'attrio/default_value/clonable'
8
8
  autoload :Symbol, 'attrio/default_value/symbol'
9
9
 
10
- class << self
10
+ class << self
11
11
  def new(attribute, value)
12
12
  Attrio::DefaultValue::Base.handle(attribute, value) || value
13
13
  end
@@ -17,7 +17,7 @@ module Attrio
17
17
  #
18
18
  def call(instance)
19
19
  self.value.call(instance, self.attribute)
20
- end
20
+ end
21
21
  end
22
22
  end
23
23
  end
@@ -19,10 +19,10 @@ module Attrio
19
19
  # Evaluates the value via value#clone
20
20
  #
21
21
  # @return [Object] evaluated value
22
- #
22
+ #
23
23
  def call(*)
24
24
  @value.clone
25
- end
25
+ end
26
26
  end
27
27
  end
28
28
  end
@@ -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
@@ -2,21 +2,20 @@
2
2
 
3
3
  module Attrio
4
4
  module Initialize
5
- def self.included(base)
6
- base.send(:extend, Attrio::Initialize::ClassMethods)
7
- end
5
+ def new(*args, &block)
6
+ obj = self.allocate
8
7
 
9
- module ClassMethods
10
- def define_attrio_new(as)
11
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
12
- def self.new(*args, &block)
13
- obj = self.allocate
14
- obj.send :initialize, *args, &block
15
- obj.send "set_#{as}_defaults"
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
@@ -2,31 +2,33 @@
2
2
 
3
3
  module Attrio
4
4
  module Inspect
5
- def self.included(base)
6
- base.send(:extend, Attrio::Inspect::ClassMethods)
7
- end
5
+ def inspect
6
+ inspection = []
8
7
 
9
- module ClassMethods
10
- def define_attrio_inspect(as)
11
- define_method(:inspect) do
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
- }.compact.join(', ')
15
-
16
- "#<#{self.class} #{inspection}>"
12
+ }
17
13
  end
14
+ end
18
15
 
19
- define_method(:inspect_attribute) do |attribute_name, instance_variable_name|
20
- value = instance_variable_get(instance_variable_name.to_s)
16
+ unless inspection.size == 0
17
+ "#<#{self.class} #{inspection.flatten.compact.join(', ')}>"
18
+ else
19
+ super
20
+ end
21
+ end
21
22
 
22
- if value.is_a?(String) && value.length > 50
23
- "#{attribute_name.to_s}[#{value.size}]: " + "#{value[0..50]}...".inspect
24
- elsif value.is_a?(Array) && value.length > 5
25
- "#{attribute_name.to_s}[#{value.size}]: " + "#{value[0..5]}...".inspect
26
- else
27
- "#{attribute_name.to_s}: " + value.inspect
28
- end
29
- end
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
@@ -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
- end
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 "set_#{as.to_s}_defaults" do |attributes = []|
22
- self.send(as.to_s, attributes).values.select{ |attribute| !attribute.default_value.nil? }.each do |attribute|
23
- next if self.send(attribute.reader_method_name).present?
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
- default_value = attribute.default_value.is_a?(Attrio::DefaultValue::Base) ? attribute.default_value.call(self) : attribute.default_value
26
- self.send(attribute.writer_method_name, default_value)
27
- end
28
- end
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
@@ -3,7 +3,7 @@
3
3
  module Attrio
4
4
  module Version
5
5
  MAJOR = 0
6
- MINOR = 5
6
+ MINOR = 6
7
7
  PATCH = 0
8
8
  BUILD = nil
9
9
 
@@ -14,7 +14,7 @@ describe 'Embedded Value' do
14
14
  end
15
15
  end
16
16
 
17
- class City
17
+ class City
18
18
  include Attrio
19
19
  include MassAssignment
20
20
 
@@ -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
@@ -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.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-07-26 00:00:00.000000000 Z
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: 1.8.24
178
+ rubygems_version: 2.0.3
199
179
  signing_key:
200
- specification_version: 3
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: