attr_coerced 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c709d08d8b9359589eeb00ffcac0c7dac9b20b07
4
- data.tar.gz: 709a619645efd382ad5f64da0653549c7e42b3e7
3
+ metadata.gz: 1c7d8d7c5757b03eff6ce66fd33d7f950538ac79
4
+ data.tar.gz: adf7da5e4929b7dd5a19018657ce96b9b84dd1f1
5
5
  SHA512:
6
- metadata.gz: b96f6ca645ca651e93e7e1b0699da0b4d2cc4e4e53f6cae129c4619e3dadd220b33962b752ac8f08ebb6db39a468418f2ec129a54c170e979392969691ad4b19
7
- data.tar.gz: 2bfa88ee0e7f23554c9f4c6a8b765a1858cec1641302d076738f50f73147cba34711cec14982f783dbecc5ac4a368e77b0c96a9bc598bdf17361d1ef6c5c095a
6
+ metadata.gz: b6e2550b927bb5ddbad0da11e937405bad95234a3bde4c7f637b9812e61662b58af5d2592c7aeb7de141742d3224633b805a6d595e253cbce28f0bac3eb15d1e
7
+ data.tar.gz: 5f75acb026ccabc72cc05fd4f5ae8f33907cd4c8c8bd960959cd61ab8f0fa0f2cc420c3318c6e207e9f958e562131629552ecda764b075a156569ed2bfad5e28
data/README.md CHANGED
@@ -21,54 +21,77 @@ Usage
21
21
  -----
22
22
 
23
23
  ```ruby
24
- class MyModel
24
+ class Foo
25
25
  extend AttrCoerced
26
+ attr_coerced :bar, Bar, default: :baz
27
+ end
28
+
29
+ class Bar < SimpleDelegator
26
30
 
27
- # @!attribute name ("foo")
28
- # @return [Name]
29
- attr_coerced :name, Name, default: "foo"
31
+ def initialize(value)
32
+ super value.to_s
33
+ end
34
+ # ... methods extending the string
30
35
  end
31
36
  ```
32
37
 
33
- This provides coerced attribute `name` (both getter and setter), defined in a following manner:
38
+ Ensure the constructor to accept instances of its own - this is necessary for the getter.
39
+
40
+ After this both the getter and setter will be redefined:
34
41
 
35
42
  ```ruby
36
- class MyModel
43
+ foo = Foo.new
37
44
 
38
- # coerced getter
39
- def name
40
- Name.new(@name ||= "foo")
41
- end
45
+ # Coerced default value is used
46
+ foo.bar.class # => Bar
47
+ foo.bar == "baz" # => true
42
48
 
43
- # coerced setter
44
- def name=(value)
45
- @name = Name.new(value)
46
- end
49
+ # Assigned value is coerced
50
+ foo.bar = :bar
51
+ foo.bar.class # => Bar
52
+ foo.bar == "bar" # => true
47
53
 
48
- end
54
+ # Reset to coerced default value
55
+ foo.bar = nil
56
+ foo.bar.class # => Bar
57
+ foo.bar == "baz" # => true
49
58
  ```
50
59
 
51
- You can use `attr_coerced_reader` and `attr_coerced_writer` to define only getter or setter. (Notice, the `attr_coerced_writer` doesn't use the `:default` option).
52
-
53
- The type of the attribute can be defined somehow like:
60
+ You can redefine getter and setter only with `attr_coerced_reader` and `attr_coerced_writer`.
54
61
 
55
62
  ```ruby
56
- class Name < String
63
+ class Foo
64
+ extend AttrCoerced
65
+ attr_coerced_writer :bar, Bar, default: :baz
66
+ end
57
67
 
58
- def self.new(value)
59
- super unless value.blank? # returns nil except for ""
60
- end
68
+ foo = Foo.new
61
69
 
62
- def initialize(value)
63
- super value.to_s
64
- end
70
+ # By default value is not coerced
71
+ foo.bar # => nil
65
72
 
66
- # ... additional methods extending the string
73
+ # The setter assigns coerced default value instead of nil
74
+ foo.bar = nil
75
+ foo.bar.class # => Bar
76
+ foo.bar == "baz" # => true
77
+ ```
67
78
 
79
+ Notice, that if a default values isn't set or is set to `nil`, no `nil` values are coerced, because `nil` stands for nothing, not something.
80
+
81
+ ```ruby
82
+ class Foo
83
+ extend AttrCoerced
84
+ att_coerced :bar, Bar
68
85
  end
69
- ```
70
86
 
71
- Ensure the constructor to accept instances of its own - this is necessary for the getter.
87
+ foo = Foo.new
88
+ # The getter doesn't coerce nil
89
+ foo.bar # => nil
90
+
91
+ # Neither the setter does
92
+ foo.bar = nil
93
+ foo.bar # => nil
94
+ ```
72
95
 
73
96
  Focus
74
97
  -----
@@ -112,6 +135,14 @@ Or add it manually:
112
135
  gem install attr_coerced
113
136
  ```
114
137
 
138
+ Changelog
139
+ ---------
140
+
141
+ ### v1.0.0
142
+
143
+ * All methods makes `nil` not coerced because it always stands for nothing.
144
+ * `#attr_coerced_writer` makes attribute setter to assign default value instead of `nil`.
145
+
115
146
  ## Compatibility
116
147
 
117
148
  Tested under rubies compatible to API 2.0+:
@@ -7,9 +7,9 @@ ClassNameCheck:
7
7
  pattern: !ruby/regexp /^[A-Z][a-zA-Z0-9]*$/
8
8
  ClassVariableCheck:
9
9
  CyclomaticComplexityBlockCheck:
10
- complexity: 2
10
+ complexity: 3
11
11
  CyclomaticComplexityMethodCheck:
12
- complexity: 2
12
+ complexity: 3
13
13
  EmptyRescueBodyCheck:
14
14
  ForLoopCheck:
15
15
  MethodLineCountCheck:
@@ -1,10 +1,12 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require_relative "attr_coerced/version"
4
+ require_relative "attr_coerced/coercer"
4
5
 
5
6
  # Namespace for the code of the 'attr_coerced' gem
6
7
  module AttrCoerced
7
8
 
9
+ # @!method attr_coerced(name, type, default: nil)
8
10
  # Defines both value getter and setter for a coercible attribute
9
11
  #
10
12
  # @example
@@ -18,11 +20,8 @@ module AttrCoerced
18
20
  # The default value for the attribute. The value will be coerced as well
19
21
  #
20
22
  # @return [Symbol] name of the attribute
21
- def attr_coerced(name, type, default: nil)
22
- [
23
- attr_coerced_reader(name, type, default: default),
24
- attr_coerced_writer(name, type)
25
- ]
23
+ def attr_coerced(*args)
24
+ [attr_coerced_reader(*args), attr_coerced_writer(*args)]
26
25
  end
27
26
 
28
27
  # Defines value getter for a coercible attribute
@@ -35,7 +34,10 @@ module AttrCoerced
35
34
  #
36
35
  # @return (see #attr_coerced)
37
36
  def attr_coerced_reader(name, type, default: nil)
38
- define_method(name) { type.new(instance_eval("@#{ name }") || default) }
37
+ define_method name do
38
+ value = instance_variable_get "@#{ name }"
39
+ Coercer.get value, default, type
40
+ end
39
41
 
40
42
  name.to_sym
41
43
  end
@@ -43,17 +45,19 @@ module AttrCoerced
43
45
  # Defines value setter for a coercible attribute
44
46
  #
45
47
  # @example
46
- # attr_coerced_writer :name, Name
48
+ # attr_coerced_writer :name, Name, default: "foo"
47
49
  #
48
50
  # @param (see #attr_coerced)
51
+ # @option (see #attr_coerced)
49
52
  #
50
53
  # @return (see #attr_coerced)
51
- def attr_coerced_writer(name, type)
54
+ def attr_coerced_writer(name, type, default: nil)
52
55
  define_method "#{ name }=" do |value|
53
- instance_eval "@#{ name } = #{ type }.new(value)"
56
+ new_value = Coercer.get value, default, type
57
+ instance_variable_set "@#{ name }", new_value
54
58
  end
55
59
 
56
- "#{ name }=".to_sym
60
+ :"#{ name }="
57
61
  end
58
62
 
59
63
  end # module AttrCoerced
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ module AttrCoerced
4
+
5
+ # @private
6
+ Coercer = Struct.new(:value, :default, :type) do
7
+
8
+ def self.get(*args)
9
+ new(*args).get
10
+ end
11
+
12
+ def get
13
+ coerce(value) || coerce(default)
14
+ end
15
+
16
+ private
17
+
18
+ def coerce(something)
19
+ something.nil? ? nil : type.new(something)
20
+ end
21
+
22
+ end # class Coercer
23
+
24
+ end # module AttrCoerced
@@ -4,6 +4,6 @@ module AttrCoerced
4
4
 
5
5
  # The semantic version of the module.
6
6
  # @see http://semver.org/ Semantic versioning 2.0
7
- VERSION = "0.0.1".freeze
7
+ VERSION = "1.0.0".freeze
8
8
 
9
9
  end # module AttrCoerced
@@ -16,88 +16,146 @@ describe AttrCoerced do
16
16
 
17
17
  describe "#attr_coerced_reader" do
18
18
 
19
- let!(:result) { test_class.attr_coerced_reader :foo, Foo, default: "bar" }
19
+ context "without a default value" do
20
20
 
21
- it "defines the getter" do
22
- expect(subject).to respond_to :foo
23
- end
21
+ let!(:result) { test_class.attr_coerced_reader :foo, Foo }
24
22
 
25
- it "makes the getter to return the default value" do
26
- value = subject.foo
23
+ it "defines the getter" do
24
+ expect(subject).to respond_to :foo
25
+ end
27
26
 
28
- expect(value).to be_kind_of Foo
29
- expect(value).to eq "bar"
30
- end
27
+ it "makes the getter to coerce the value" do
28
+ subject.instance_eval "@foo = \"baz\""
29
+ value = subject.foo
31
30
 
32
- it "makes the getter to coerce the value" do
33
- subject.instance_eval "@foo = \"baz\""
34
- value = subject.foo
31
+ expect(value).to be_kind_of Foo
32
+ expect(value).to eq "baz"
33
+ end
35
34
 
36
- expect(value).to be_kind_of Foo
37
- expect(value).to eq "baz"
38
- end
35
+ it "makes the getter not to coerce nil" do
36
+ subject.instance_eval "@foo = nil"
37
+ value = subject.foo
39
38
 
40
- it "returns the name of the attribute" do
41
- expect(result).to eq :foo
42
- end
39
+ expect(value).to be_nil
40
+ end
41
+
42
+ it "returns the name of the attribute" do
43
+ expect(result).to eq :foo
44
+ end
45
+
46
+ end # context
47
+
48
+ context "with a default value" do
49
+
50
+ let!(:result) { test_class.attr_coerced_reader :foo, Foo, default: "bar" }
51
+
52
+ it "defines the getter" do
53
+ expect(subject).to respond_to :foo
54
+ end
55
+
56
+ it "makes the getter to return the default value" do
57
+ value = subject.foo
58
+
59
+ expect(value).to be_kind_of Foo
60
+ expect(value).to eq "bar"
61
+ end
62
+
63
+ it "makes the getter to coerce the value" do
64
+ subject.instance_eval "@foo = \"baz\""
65
+ value = subject.foo
66
+
67
+ expect(value).to be_kind_of Foo
68
+ expect(value).to eq "baz"
69
+ end
70
+
71
+ it "returns the name of the attribute" do
72
+ expect(result).to eq :foo
73
+ end
74
+
75
+ end # context
43
76
 
44
77
  end # describe #attr_coerced_reader
45
78
 
46
79
  describe "#attr_coerced_writer" do
47
80
 
48
- let!(:result) { test_class.attr_coerced_writer :foo, Foo }
81
+ context "without a default value" do
49
82
 
50
- it "defines the setter" do
51
- expect(subject).to respond_to :foo=
52
- end
83
+ let!(:result) { test_class.attr_coerced_writer :foo, Foo }
84
+
85
+ it "defines the setter" do
86
+ expect(subject).to respond_to :foo=
87
+ end
53
88
 
54
- it "makes the setter to coerce the value" do
55
- subject.foo = "baz"
56
- value = subject.instance_eval "@foo"
89
+ it "makes the setter to coerce the value" do
90
+ subject.foo = "baz"
91
+ value = subject.instance_eval "@foo"
57
92
 
58
- expect(value).to be_kind_of Foo
59
- expect(value).to eq "baz"
60
- end
93
+ expect(value).to be_kind_of Foo
94
+ expect(value).to eq "baz"
95
+ end
61
96
 
62
- it "returns the name of the attribute" do
63
- expect(result).to eq :foo=
64
- end
97
+ it "makes the setter not to coerce nil" do
98
+ subject.foo = nil
99
+ value = subject.instance_eval "@foo"
65
100
 
66
- end # describe #attr_coerced_writer
101
+ expect(value).to be_nil
102
+ end
67
103
 
68
- describe "#attr_coerced" do
104
+ it "returns the name of the attribute" do
105
+ expect(result).to eq :foo=
106
+ end
69
107
 
70
- let!(:result) { test_class.attr_coerced :foo, Foo, default: "bar" }
108
+ end # context
71
109
 
72
- it "defines the getter" do
73
- expect(subject).to respond_to :foo
74
- end
110
+ context "with a default value" do
75
111
 
76
- it "makes the getter to return the default value" do
77
- value = subject.foo
112
+ let!(:result) { test_class.attr_coerced_writer :foo, Foo, default: "bar" }
78
113
 
79
- expect(value).to be_kind_of Foo
80
- expect(value).to eq "bar"
81
- end
114
+ it "defines the setter" do
115
+ expect(subject).to respond_to :foo=
116
+ end
82
117
 
83
- it "makes the getter to coerce the value" do
84
- subject.instance_eval "@foo = \"baz\""
85
- value = subject.foo
118
+ it "makes the setter to coerce the value" do
119
+ subject.foo = "baz"
120
+ value = subject.instance_eval "@foo"
86
121
 
87
- expect(value).to be_kind_of Foo
88
- expect(value).to eq "baz"
89
- end
122
+ expect(value).to be_kind_of Foo
123
+ expect(value).to eq "baz"
124
+ end
90
125
 
91
- it "defines the setter" do
92
- expect(subject).to respond_to :foo=
93
- end
126
+ it "makes the setter to use default instead of nil" do
127
+ subject.foo = nil
128
+ value = subject.instance_eval "@foo"
129
+
130
+ expect(value).to be_kind_of Foo
131
+ expect(value).to eq "bar"
132
+ end
133
+
134
+ it "returns the name of the attribute" do
135
+ expect(result).to eq :foo=
136
+ end
137
+
138
+ end # context
94
139
 
95
- it "makes the setter to coerce the value" do
96
- subject.foo = "baz"
97
- value = subject.instance_eval "@foo"
140
+ end # describe #attr_coerced_writer
141
+
142
+ describe "#attr_coerced" do
143
+
144
+ let(:options) { [:foo, Foo, default: "bar"] }
145
+ let(:result) { test_class.attr_coerced(*options) }
146
+
147
+ it "calls #attr_coerced_reader" do
148
+ expect(test_class)
149
+ .to receive(:attr_coerced_reader)
150
+ .with(*options)
151
+ result
152
+ end
98
153
 
99
- expect(value).to be_kind_of Foo
100
- expect(value).to eq "baz"
154
+ it "calls #attr_coerced_writer" do
155
+ expect(test_class)
156
+ .to receive(:attr_coerced_writer)
157
+ .with(*options)
158
+ result
101
159
  end
102
160
 
103
161
  it "returns the names of the methods" do
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attr_coerced
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kozin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-30 00:00:00.000000000 Z
11
+ date: 2015-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hexx-rspec
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.4'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.4'
27
27
  description: Coerced attributes for PORO models.
@@ -32,13 +32,13 @@ extra_rdoc_files:
32
32
  - README.md
33
33
  - LICENSE
34
34
  files:
35
- - .coveralls.yml
36
- - .gitignore
37
- - .metrics
38
- - .rspec
39
- - .rubocop.yml
40
- - .travis.yml
41
- - .yardopts
35
+ - ".coveralls.yml"
36
+ - ".gitignore"
37
+ - ".metrics"
38
+ - ".rspec"
39
+ - ".rubocop.yml"
40
+ - ".travis.yml"
41
+ - ".yardopts"
42
42
  - Gemfile
43
43
  - Guardfile
44
44
  - LICENSE
@@ -57,6 +57,7 @@ files:
57
57
  - config/metrics/simplecov.yml
58
58
  - config/metrics/yardstick.yml
59
59
  - lib/attr_coerced.rb
60
+ - lib/attr_coerced/coercer.rb
60
61
  - lib/attr_coerced/version.rb
61
62
  - spec/spec_helper.rb
62
63
  - spec/tests/attr_coerced_spec.rb
@@ -70,12 +71,12 @@ require_paths:
70
71
  - lib
71
72
  required_ruby_version: !ruby/object:Gem::Requirement
72
73
  requirements:
73
- - - ~>
74
+ - - "~>"
74
75
  - !ruby/object:Gem::Version
75
76
  version: '2.0'
76
77
  required_rubygems_version: !ruby/object:Gem::Requirement
77
78
  requirements:
78
- - - '>='
79
+ - - ">="
79
80
  - !ruby/object:Gem::Version
80
81
  version: '0'
81
82
  requirements: []