attr_extras 1.9.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -16
- data/lib/attr_extras/version.rb +1 -1
- data/lib/attr_extras.rb +6 -4
- data/spec/attr_extras_spec.rb +52 -11
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d86d1ce2f78e900f9dd4c9792df912f94ed6973f
|
4
|
+
data.tar.gz: 41d756b1d2b14f6f66ce1b8eb7e0127b4839d9b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f4c36e7c979590d62a5a8fccc7f450eda9ec9cb1cd21466b8634c995b9bd2921bf1edbab33a09e85a7136f618d4e99ace7a3d8c70701420d216eb3b67695710
|
7
|
+
data.tar.gz: 4eb369edb50ea00c9bfdb36f78053cfdbabecd9ce826050fa8d588ede9942e72ebefa064ed2b05f10edaf4b4f58be2e9cf347919892c5d74dbee34312a6f45df
|
data/README.md
CHANGED
@@ -31,37 +31,72 @@ This nicely complements Ruby's built-in `attr_accessor`, `attr_reader` and `attr
|
|
31
31
|
|
32
32
|
## Usage
|
33
33
|
|
34
|
-
|
34
|
+
|
35
|
+
### `attr_initialize :foo, :bar`
|
36
|
+
|
35
37
|
Defines an initializer that takes two arguments and assigns `@foo` and `@bar`.
|
36
38
|
|
37
|
-
`attr_initialize :foo, [:bar, :baz!]`,
|
38
|
-
|
39
|
+
`attr_initialize :foo, [:bar, :baz!]` defines an initializer that takes one regular argument, assigning `@foo`, and one hash argument, assigning `@bar` (optional) and `@baz` (required).
|
40
|
+
|
41
|
+
`attr_initialize [:bar, :baz!]` defines an initializer that takes one hash argument, assigning `@bar` (optional) and `@baz` (required).
|
42
|
+
|
39
43
|
|
40
|
-
`
|
41
|
-
Defines an initializer that takes one hash argument, assigning `@bar` (optional) and `@baz` (required).
|
44
|
+
### `attr_private :foo, :bar`
|
42
45
|
|
43
|
-
`attr_private :foo, :bar`<br>
|
44
46
|
Defines private readers for `@foo` and `@bar`.
|
45
47
|
|
46
|
-
`pattr_initialize :foo, :bar`<br>
|
47
|
-
Defines both initializer and private readers. The `[]` notation for hash arguments is also supported.
|
48
48
|
|
49
|
-
`attr_value :foo, :bar
|
50
|
-
|
51
|
-
Defines
|
49
|
+
### `attr_value :foo, :bar`
|
50
|
+
|
51
|
+
Defines public readers. Does not define writers, as value objects are typically immutable.
|
52
|
+
|
53
|
+
Defines object equality: two value objects of the same class with the same values are equal.
|
54
|
+
|
55
|
+
|
56
|
+
### `pattr_initialize :foo, :bar`
|
57
|
+
|
58
|
+
Defines both initializer and private readers: shortcut for
|
59
|
+
|
60
|
+
```
|
61
|
+
attr_initialize :foo, :bar
|
62
|
+
attr_private :foo, :bar
|
63
|
+
```
|
64
|
+
|
65
|
+
The `attr_initialize` notation notation for hash arguments is also supported: `pattr_initialize :foo, [:bar, :baz!]`
|
66
|
+
|
52
67
|
|
53
|
-
`
|
54
|
-
|
68
|
+
### `vattr_initialize :foo, :bar`
|
69
|
+
|
70
|
+
Defines initializer, public readers and value object identity: shortcut for
|
71
|
+
|
72
|
+
```
|
73
|
+
attr_initialize :foo, :bar
|
74
|
+
attr_value :foo, :bar
|
75
|
+
```
|
76
|
+
|
77
|
+
The `attr_initialize` notation notation for hash arguments is also supported: `vattr_initialize :foo, [:bar, :baz!]`
|
78
|
+
|
79
|
+
|
80
|
+
### `method_object :fooable?, :foo`<br>
|
81
|
+
|
82
|
+
Defines a `.fooable?` class method that takes one argument (`:foo`) and delegates to an instance method that can access `foo` as a private reader, useful for [method objects](http://refactoring.com/catalog/replaceMethodWithMethodObject.html).
|
83
|
+
|
84
|
+
The `attr_initialize` notation notation for hash arguments is also supported: `method_object :fooable?, :foo, [:bar, :baz!]`
|
55
85
|
|
56
86
|
You don't have to specify readers if you don't want them: `method_object :fooable?` is also valid.
|
57
87
|
|
58
|
-
|
88
|
+
|
89
|
+
### `attr_id_query :foo?, :bar?`<br>
|
59
90
|
Defines query methods like `foo?`, which is true iff `foo_id` is truthy. Goes well with Active Record.
|
60
91
|
|
61
|
-
|
92
|
+
|
93
|
+
### `attr_query :foo?, :bar?`<br>
|
62
94
|
Defines query methods like `foo?`, which is true iff `foo` is truthy.
|
63
95
|
|
64
|
-
|
96
|
+
|
97
|
+
## Philosophy
|
98
|
+
|
99
|
+
Findability is a core value.
|
65
100
|
Hence the long name `attr_initialize`, so you see it when scanning for the initializer;
|
66
101
|
and the enforced questionmarks with `attr_id_query :foo?`, so you can search for that method.
|
67
102
|
|
data/lib/attr_extras/version.rb
CHANGED
data/lib/attr_extras.rb
CHANGED
@@ -47,16 +47,18 @@ module AttrExtras
|
|
47
47
|
attr_private *attr_flat_names(names)
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
50
|
+
def vattr_initialize(*names)
|
51
51
|
attr_initialize(*names)
|
52
|
+
attr_value *attr_flat_names(names)
|
53
|
+
end
|
52
54
|
|
53
|
-
|
54
|
-
attr_reader *
|
55
|
+
def attr_value(*names)
|
56
|
+
attr_reader *names
|
55
57
|
|
56
58
|
define_method(:==) do |other|
|
57
59
|
return false unless other.is_a?(self.class)
|
58
60
|
|
59
|
-
|
61
|
+
names.all? { |attr| self.public_send(attr) == other.public_send(attr) }
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
data/spec/attr_extras_spec.rb
CHANGED
@@ -117,34 +117,50 @@ describe Object, ".pattr_initialize" do
|
|
117
117
|
end
|
118
118
|
|
119
119
|
example = klass.new("Foo", :bar => "Bar", :baz => "Baz")
|
120
|
-
example.send(:bar).must_equal "Bar"
|
121
120
|
example.send(:baz).must_equal "Baz"
|
122
121
|
end
|
123
122
|
end
|
124
123
|
|
125
|
-
describe Object, ".
|
126
|
-
it "creates
|
124
|
+
describe Object, ".vattr_initialize" do
|
125
|
+
it "creates initializer, value readers and value object identity" do
|
127
126
|
klass = Class.new do
|
128
|
-
|
127
|
+
vattr_initialize :foo, :bar
|
129
128
|
end
|
130
129
|
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
example1 = klass.new("Foo", "Bar")
|
131
|
+
example2 = klass.new("Foo", "Bar")
|
132
|
+
|
133
|
+
example1.foo.must_equal "Foo"
|
134
|
+
example1.must_equal example2
|
134
135
|
end
|
135
136
|
|
136
137
|
it "works with hash ivars" do
|
137
138
|
klass = Class.new do
|
138
|
-
|
139
|
+
vattr_initialize :foo, [:bar, :baz!]
|
139
140
|
end
|
140
141
|
|
141
|
-
|
142
|
-
|
143
|
-
|
142
|
+
example1 = klass.new("Foo", :bar => "Bar", :baz => "Baz")
|
143
|
+
example2 = klass.new("Foo", :bar => "Bar", :baz => "Baz")
|
144
|
+
example1.baz.must_equal "Baz"
|
145
|
+
example1.must_equal example2
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe Object, ".attr_value" do
|
150
|
+
it "creates public readers" do
|
151
|
+
klass = Class.new do
|
152
|
+
attr_value :foo, :bar
|
153
|
+
end
|
154
|
+
|
155
|
+
example = klass.new
|
156
|
+
example.instance_variable_set("@foo", "Foo")
|
157
|
+
example.foo.must_equal "Foo"
|
158
|
+
lambda { example.foo = "new value" }.must_raise NoMethodError
|
144
159
|
end
|
145
160
|
|
146
161
|
it "defines equality based on the attributes" do
|
147
162
|
klass = Class.new do
|
163
|
+
attr_initialize :foo, :bar
|
148
164
|
attr_value :foo, :bar
|
149
165
|
end
|
150
166
|
|
@@ -155,14 +171,17 @@ describe Object, ".attr_value" do
|
|
155
171
|
assert example1 == example2, "Examples should be equal"
|
156
172
|
refute example1 != example2, "Examples should be equal"
|
157
173
|
|
174
|
+
refute example1 == example3, "Examples should not be equal"
|
158
175
|
assert example1 != example3, "Examples should not be equal"
|
159
176
|
end
|
160
177
|
|
161
178
|
it "defines equality based on the actual type" do
|
162
179
|
klass1 = Class.new do
|
180
|
+
attr_initialize :foo
|
163
181
|
attr_value :foo
|
164
182
|
end
|
165
183
|
klass2 = Class.new do
|
184
|
+
attr_initialize :foo
|
166
185
|
attr_value :foo
|
167
186
|
end
|
168
187
|
|
@@ -172,6 +191,28 @@ describe Object, ".attr_value" do
|
|
172
191
|
assert example1 != example2, "Examples should not be equal"
|
173
192
|
refute example1 == example2, "Examples should not be equal"
|
174
193
|
end
|
194
|
+
|
195
|
+
it "considers an instance equal to itself" do
|
196
|
+
klass = Class.new do
|
197
|
+
attr_initialize :foo
|
198
|
+
attr_value :foo
|
199
|
+
end
|
200
|
+
|
201
|
+
instance = klass.new("Foo")
|
202
|
+
|
203
|
+
assert instance == instance, "Instance should be equal to itself"
|
204
|
+
end
|
205
|
+
|
206
|
+
it "can compare value objects to other kinds of objects" do
|
207
|
+
klass = Class.new do
|
208
|
+
attr_initialize :foo
|
209
|
+
attr_value :foo
|
210
|
+
end
|
211
|
+
|
212
|
+
instance = klass.new("Foo")
|
213
|
+
|
214
|
+
assert instance != "a string"
|
215
|
+
end
|
175
216
|
end
|
176
217
|
|
177
218
|
describe Object, ".attr_id_query" do
|