attrio 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: