kv_accessor 0.1.0 → 0.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd61aa81ee2bcd6db26543b002c1916d366a1738
4
- data.tar.gz: 2c2095c33a8d941b8c3d5325d9555e1bf5cfc455
3
+ metadata.gz: a9825ad1d5e43106077b0948d9a7338ea0702554
4
+ data.tar.gz: f457ccbc9724f7e90ade499797c94c7d52ef7941
5
5
  SHA512:
6
- metadata.gz: 43edfb17fa1d2e34ade55e2a7b909ca6a8bfa7bcd2d788daff5c8d5f049227a85cdc72c1abea050476ea0add7b657e37ac1155653867f657479a30937fc932da
7
- data.tar.gz: 6d2fa5e256730c6d25869499be0a30e1461b14dc0a96a0a810706912642e7d94c58dacee498e2db4b44d2dd12737eab0438431b294e26616309344acf1c8b734
6
+ metadata.gz: d16a8b478d0431850f57dfab61efa763b99c5fa337dec5d13ba8093d9e8bce5c58af3c435e682b802475895de509134510858b0d463e6afbf06d9d5d16093b72
7
+ data.tar.gz: ed2ca4e9fe6f37f040e562f3238307b1f4261a34300402bf24a4a3bcc0d526bfc7269e0521e28b26bb2735dc5aa5de9ec433089b107e9893cb0fe6fb97f7f5e2
@@ -0,0 +1,17 @@
1
+ # Change Log
2
+ All notable changes to this project will be documented in this file.
3
+ This project adheres to [Semantic Versioning](http://semver.org/).
4
+
5
+ ## 0.1.1 - 2016-03-28
6
+ ### Added
7
+ - README.md and CHANGELOG.md content.
8
+
9
+ ### Changed
10
+ - `KvAccessor.kv_accessor`/`.kv_reader`/`.kv_writer` now return the hash of
11
+ `accessor_name => key` to have more meaning.
12
+ - Refactored/edited some of the specs.
13
+
14
+ ### Fixed
15
+ - Some of the documentation
16
+
17
+ [Unreleased]: https://github.com/olivierlacan/keep-a-changelog/compare/v0.1.0...HEAD
data/README.md CHANGED
@@ -0,0 +1,221 @@
1
+ KvAccessor
2
+ ==========
3
+
4
+ Define reader and writer accessor methods for an attribute/method that quacks
5
+ like a Hash (`respond_to?(:[])`).
6
+
7
+ ```ruby
8
+ class MyCar
9
+ extend KvAccessors
10
+ attr_accessor :details
11
+
12
+ kv_accessor :details, :make, 'model'
13
+
14
+ def initialize(details = {})
15
+ self.details = details
16
+ end
17
+ end
18
+
19
+ car = MyCar.new(:make => 'Chevrolet', 'model' => 'Camaro')
20
+ car.make #=> "Chevrolet"
21
+ car.model #=> "Camaro"
22
+ ```
23
+
24
+ Installation
25
+ ------------
26
+
27
+ Gem
28
+
29
+ ```terminal
30
+ $ gem install kv_accessor
31
+ ```
32
+
33
+ Bundler
34
+
35
+ ```ruby
36
+ gem 'kv_accessor'
37
+ ```
38
+
39
+ Usage
40
+ -----
41
+
42
+ Easily encapsulate Hash like objects.
43
+
44
+ The reader/writer can be named separately from the `#[]`/`#[]=` key via an
45
+ alias_accessors argument (this allows for aliasing of complex keys or class
46
+ differences like Symbol vs. String).
47
+
48
+ No initializer is implemented, so any needed initialization is up to the owner.
49
+
50
+ A word of warning: `#inspect` is called on the `:[]` key the implimentation is
51
+ via `class_eval`. `#to_s` is called on the passed `method` name and the method
52
+ is called without regard to the receiver (eg. a Kernel method can be called
53
+ if no instance method overrides it).
54
+
55
+ No guarding against user input exists. Only values should come from user input.
56
+
57
+ Meant as a DSL for creating value style objects that encapsulate a Hash object
58
+ so as to avoid inheriting from Hash/OpenStruct. Take a look at Struct,
59
+ OpenStruct, and [Virtus](https://github.com/solnic/virtus) for alternatives with
60
+ other features.
61
+
62
+ An extended example:
63
+
64
+ ```ruby
65
+ class MyCar
66
+ attr_accessor :details
67
+ extend KvAccessors
68
+
69
+ kv_accessor :details, :make, :year => 'model_year',
70
+ :blue_interior_cost => { 'leather' => 'blue' }
71
+ kv_reader :details, 'model', :ac?, :seats
72
+ kv_writer :details, 'price'
73
+
74
+ def initialize(details = {})
75
+ self.details = details
76
+ end
77
+ end
78
+
79
+ c = MyCar.new(:make => 'Chevrolet', 'model' => 'Camaro', 'model_year' => 1967,
80
+ 'submodel' => 'SS', 'price' => 20_000.00, :ac? => true,
81
+ :seats => 4, { 'leather' => 'blue' } => 2_000.00)
82
+ c.make
83
+ #=> "Chevrolet"
84
+ c.model
85
+ #=> "Camaro"
86
+
87
+ # Even though the 'submodel' is a part of 'details', all the attributes need to
88
+ # be specified.
89
+ c.submodel
90
+ #=> NoMethodError
91
+
92
+ # '#model' was defined as a kv_reader only
93
+ c.model = 'Corvette'
94
+ #=> NoMethodError
95
+
96
+ # Full on accessor
97
+ c.year
98
+ #=> 1967
99
+ c.year = 1968
100
+ #=> 1968
101
+ c.year
102
+ #=> 1968
103
+ c.details['model_year']
104
+ #=> 1968
105
+
106
+ # Using a complex key with alias.
107
+ # This example is a little contrived, but this has plenty of uses, like using
108
+ # classes as keys.
109
+ # This example key lookup would be:
110
+ # 'details[{ 'leather' => 'blue' }]'
111
+ c.blue_interior_cost
112
+ #=> 2_000.00
113
+ c.blue_interior_cost = 4_000.00
114
+ #=> 4_000.00
115
+ c.details[{ 'leather' => 'blue' }]
116
+ #=> 4_000.00
117
+
118
+ # kv_writer with no reader present
119
+ c.price
120
+ #=> NoMethodError
121
+ c.price = 25_000.00
122
+ #=> 25_000.00
123
+ c.details['price']
124
+ #=> 25_000.00
125
+
126
+ c.details
127
+ #=> { :make => "Chevrolet", "model" => "Camaro", "model_year" => 1967,
128
+ # "submodel" => "SS", { "leather" => "blue" } => 4_000.00,
129
+ # "price" => 25_000.00}
130
+ ```
131
+
132
+ Can be used for whatever attributes respond to '#[]'/'#[]='.
133
+
134
+ ```ruby
135
+ class Employee < ActiveRecord::Base
136
+ store :settings, coder: JSON
137
+ has_one :office
138
+ extend KvAccessors
139
+
140
+ # Could just use a normal delegator here, but this shows any object with a
141
+ # '#[]'/'#[]=' can work since ActiveRecord models define a '#[]' interface
142
+ # for their columns.
143
+ kv_reader :office, 'chair', 'table'
144
+
145
+ # Define for as many attributes as you like
146
+ kv_accessor :settings, 'wallpaper', :language
147
+
148
+ after_initialize { settings ||= {} }
149
+ end
150
+
151
+ c = Employee.new
152
+
153
+ # Since an '#office' hasn't been assigned yet, this will try to call '#[]' on
154
+ # nil. Best to always set a default like 'settings' in 'after_initialize'.
155
+ c.chair
156
+ #=> NoMethodError
157
+
158
+ c.office = Office.new(chair: true, table: false)
159
+ c.chair
160
+ #=> true
161
+
162
+ c.wallpaper = 'birdy'
163
+ ```
164
+
165
+ Since the kv_accessor/reader/writer methods return a hash, an easy pattern to
166
+ manage the accessors during runtime would be to assign the result to a const.
167
+
168
+ ```ruby
169
+ class MyCar
170
+ extend KvAccessors
171
+
172
+ attr_accessor :details
173
+
174
+ # The kv_* methods return a hash of 'attribute_name => key' for convenience.
175
+ # I like to use this to easily filter out keys in the initializer.
176
+ SERIALIZABLE_ACCESSORS =
177
+ kv_accessor :details, :make, :year => 'model_year',
178
+ :blue_interior_cost => { 'leather' => 'blue' }
179
+
180
+ SERIALIZABL_READERS = SERIALIZABLE_ACCESSORS.merge(
181
+ kv_writer :details, 'model'
182
+ )
183
+
184
+ SERIALIZABLE_WRITERS = SERIALIZABLE_ACCESSORS.merge(
185
+ kv_writer :details, 'price'
186
+ )
187
+
188
+ def initialize(details = {})
189
+ self.details = details
190
+ end
191
+
192
+ def serializable_hash
193
+ ACCESSORS.merge(READERS).merge(WRITERS)
194
+ .map { |name, key| [name.to_s, details[key]] }.to_h
195
+ end
196
+ end
197
+
198
+ c = Car.new(:make => 'Chevrolet', 'model' => 'Camaro', 'model_year' => 1967,
199
+ 'submodel' => 'SS', 'price' => 25_000.00,
200
+ { 'leather' => 'blue' } => 4000.00)
201
+
202
+ c.serializable_hash
203
+ #=> { "make" => "Chevrolet", "model" => "Camaro", "year" => 1967,
204
+ # "blue_interior_cost" => 4000.00, "price" => 25_000.00}
205
+ ```
206
+
207
+ Resources
208
+ ---------
209
+
210
+ [rubydoc.info documentation](http://www.rubydoc.info/gems/kv_accessor)
211
+
212
+ Contributing
213
+ ------------
214
+
215
+ Normal github PR flow.
216
+
217
+
218
+ LICENSE
219
+ -------
220
+
221
+ 3 Clause BSD
@@ -1,9 +1,9 @@
1
1
  # Define reader and writer accessors for a Hash like instance method.
2
2
  #
3
3
  # Define reader and writer methods for a method returning a duck that quacks
4
- # like a Hash (`respond_to?(:[]`). The reader/writer can be named separately
5
- # from the ':[]' key via the alias_accessors argument (this allows for aliasing
6
- # of complex keys).
4
+ # like a Hash (`respond_to?(:[])`). The reader/writer can be named separately
5
+ # from the '#[]'/'#[]=' key via the alias_accessors argument (this allows for
6
+ # aliasing of complex keys or types).
7
7
  #
8
8
  # A word of warning: '#inspect' is called on the ':[]' key,
9
9
  # '#to_s' is called on the 'key' name and the implimentation is via
@@ -11,8 +11,10 @@
11
11
  # is called without regard to the receiver (eg. a Kernel method can be called
12
12
  # if no instance method overrides it).
13
13
  #
14
- # This is purely meant to be a DSL for creating value style objects. Take a look
15
- # at Struct, OpenStruct, and Virtus before choosing this.
14
+ # Meant as a DSL for creating value style objects that encapsulate a Hash object
15
+ # so as to avoid hacks like inheriting from Hash/OpenStruct. Take a look at
16
+ # Struct, OpenStruct, and [Virtus](https://github.com/solnic/virtus) for
17
+ # alternatives with other features.
16
18
  #
17
19
  # @example
18
20
  # class MyCar
@@ -20,7 +22,7 @@
20
22
  # extend KvAccessors
21
23
  # kv_accessor :details, :make, year: 'model_year',
22
24
  # options: { 'leather' => 'blue' }
23
- # kv_reader 'model'
25
+ # kv_reader :details, 'model'
24
26
  #
25
27
  # def initialize(details = {})
26
28
  # @details = details
@@ -96,28 +98,42 @@ module KvAccessor
96
98
  # c.details
97
99
  # #=> { :make => "Chevrolet", "model" => "Camaro", :model_year => 1968,
98
100
  # # "submodel" => "SS"
101
+ #
102
+ # @param keys [#to_s] used for both the key and the attribute name
103
+ # @param aliased_accessors [Hash< #to_s, #inspect >] the key of
104
+ # aliased_accessors is used as the attribute method name and the value of
105
+ # aliased_accessors is used as the first argument to `#[]`/`#[]=` off
106
+ # `method`
107
+ #
108
+ # @return [Hash] all the attribute name => method[key] so this method can be
109
+ # meaningfully chained.
110
+ # @example
111
+ # class Employee
112
+ # attr_accessor :info
113
+ # ATTRIBUTES = kv_accessor :info, :ssid, :dob
114
+ #
115
+ # def initalize(info)
116
+ # self.info = info.select { |k, v| ATTRIBUTES.key?(k) }
117
+ # end
118
+ # end
99
119
  def kv_accessor(method, *keys, **aliased_accessors)
100
- kv_reader(method, *keys, **aliased_accessors)
101
- kv_writer(method, *keys, **aliased_accessors)
120
+ kv_reader(method, *keys, **aliased_accessors).merge(
121
+ kv_writer(method, *keys, **aliased_accessors)
122
+ )
102
123
  end
103
124
 
104
125
  # Define reader accessors for a Hash like instance method.
105
126
  #
106
- # Define reader accessor methods for each +keys+. Accessors named other than
107
- # the key name can be defined via +aliased_accessors+. Calls to +name+ will
108
- # call ':[]' on +method+ with either +key+ or the value described via
109
- # +aliased_accessors+.
110
- #
111
- # See the overall {KvAccessors} docs for a better definition of what gets
112
- # called on what.
113
- #
114
- # This is not guarded against any sort of user input. You have been warned.
127
+ # Define reader accessor methods for each keys+. Accessors named other than
128
+ # the key name can be defined via +aliased_accessors+. Calls to either a
129
+ # +keys+ attribute name or the key of +aliased_accessor+ will call ':[]' off
130
+ # of +method+ with either +key+ or the value described via +aliased_accessors+.
115
131
  #
116
132
  # @example
117
133
  # class MyCar
118
134
  # attr_accessor :details
119
135
  # extend KvAccessors
120
- # kv_accessor :details, :make, 'model', year: :model_year
136
+ # kv_reader :details, :make, 'model', year: :model_year
121
137
  #
122
138
  # def initialize(details = {})
123
139
  # @details = details
@@ -129,12 +145,40 @@ module KvAccessor
129
145
  # c.make #=> "Chevrolet"
130
146
  # c.model #=> "Camaro"
131
147
  # c.year #=> 1967
132
- # c.year = 1968
133
- # c.year #=> 1968
148
+ # c.year = 1968 #=> NoMethodError
134
149
  # c.submodel #=> NoMethodError
135
150
  # c.details
136
- # #=> { :make => "Chevrolet", "model" => "Camaro", :model_year => 1968,
151
+ # #=> { :make => "Chevrolet", "model" => "Camaro", :model_year => 1967,
137
152
  # "submodel" => "SS" }
153
+ #
154
+ # See the overall {KvAccessors} docs for a better definition of what gets
155
+ # called on what.
156
+ #
157
+ # This is not guarded against any sort of user input. You have been warned.
158
+ #
159
+ # @see kv_accessor
160
+ #
161
+ # @param keys [#to_s] used for both the key and the attribute name
162
+ # @param aliased_accessors [Hash< #to_s, #inspect >] the key of
163
+ # aliased_accessors is used as the attribute method name and the value of
164
+ # aliased_accessors is used as the argument to `#[]` off `method`
165
+ #
166
+ # @return [Hash] all the attribute name => method[key] so this method can be
167
+ # meaningfully chained.
168
+ # @example
169
+ # class Employee
170
+ # attr_accessor :info
171
+ # ATTRIBUTES = kv_reader :info, :ssid, :birth
172
+ #
173
+ # def initalize(info)
174
+ # self.info = info.select { |k, v| ATTRIBUTES.key?(k) }
175
+ # end
176
+ # end
177
+ # employee = Employee.new(ssid: '123-456-7890', birth: '1979-06-23',
178
+ # eye_color: 'brown')
179
+ # employee.birth #=> '1979-06-23'
180
+ # employee.info
181
+ # #=> { ssid: '123-456-7890', birth: '1979-06-23' }
138
182
  def kv_reader(method, *keys, **aliased_accessors)
139
183
  accessors = Hash[keys.map { |v| [v, v] }].merge(aliased_accessors)
140
184
  accessors.each do |name, key|
@@ -157,15 +201,11 @@ module KvAccessor
157
201
  # Define writter accessors for a Hash like instance method.
158
202
  #
159
203
  # Define writter accessor methods for each +keys+. Accessors named other than
160
- # the key name can be defined via +aliased_accessors+. Calls to +name+ will
161
- # call ':[]' on +method+ with either +key+ or the value described via
204
+ # the key name can be defined via +aliased_accessors+. Calls to either a
205
+ # +keys+ attribute name or the key of +aliased_accessor+ will call '#:[]=' off
206
+ # of +method+ with either +key+ or the value described via
162
207
  # +aliased_accessors+.
163
208
  #
164
- # See the overall {KvAccessors} docs for a better definition of what gets
165
- # called on what.
166
- #
167
- # This is not guarded against any sort of user input. You have been warned.
168
- #
169
209
  # @example
170
210
  # class MyCar
171
211
  # attr_accessor :details
@@ -193,6 +233,36 @@ module KvAccessor
193
233
  # c.details
194
234
  # #=> { :make => "Chevrolet", "model" => "Corvette", :model_year => 1968,
195
235
  # # "submodel" => "SS"
236
+ #
237
+ # See the overall {KvAccessors} docs for a better definition of what gets
238
+ # called on what.
239
+ #
240
+ # This is not guarded against any sort of user input. You have been warned.
241
+ #
242
+ # @see kv_accessor
243
+ #
244
+ # @param keys [#to_s] used for both the key and the attribute name
245
+ # @param aliased_accessors [Hash< #to_s, #inspect >] the key of
246
+ # aliased_accessors is used as the attribute method name and the value of
247
+ # aliased_accessors is used as the argument to `#[]=` off `method`
248
+ #
249
+ # @return [Hash] all the attribute name => method[key] so this method can be
250
+ # meaningfully chained.
251
+ # @example
252
+ # class Employee
253
+ # attr_accessor :info
254
+ # ATTRIBUTES = kv_writer :info, :ssid, :birth
255
+ #
256
+ # def initalize(info)
257
+ # self.info = info.select { |k, v| ATTRIBUTES.key?(k) }
258
+ # end
259
+ # end
260
+ #
261
+ # employee = Employee.new(ssid: '123-456-7890', birth: '1979-06-23',
262
+ # eye_color: 'brown')
263
+ # employee.ssid = '555-555-5555'
264
+ # employee.info
265
+ # #=> { ssid: '555-555-5555', birth: '1979-06-23' }
196
266
  def kv_writer(method, *keys, **aliased_accessors)
197
267
  accessors = Hash[keys.map { |v| [v, v] }].merge(aliased_accessors)
198
268
  accessors.each do |name, key|
@@ -1,3 +1,3 @@
1
1
  module KvAccessor
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -16,12 +16,21 @@ RSpec.describe KvAccessor do
16
16
  attr_accessor :details, :other
17
17
  extend KvAccessor
18
18
 
19
- kv_accessor :details, :make, year: 'model_year',
20
- blue_interior: { 'leather' => 'blue' }
21
- kv_reader :details, 'model', :price
22
- kv_writer :details, 'color', :price
19
+ # The self is required for consts in anonymous classes.
20
+ self::DETAILS_ACCESSORS =
21
+ kv_accessor :details, :make, year: 'model_year',
22
+ blue_interior: { 'leather' => 'blue' }
23
23
 
24
- kv_accessor :other, :upc
24
+ self::DETAILS_READERS = self::DETAILS_ACCESSORS.merge(
25
+ kv_reader :details, 'model', :price
26
+ )
27
+
28
+ self::DETAILS_WRITERS = self::DETAILS_ACCESSORS.merge(
29
+ kv_writer :details, 'color', :price
30
+ )
31
+
32
+ self::OTHER_ACCESSORS =
33
+ kv_accessor :other, :upc
25
34
 
26
35
  def initialize(details, other)
27
36
  self.details = details
@@ -33,46 +42,74 @@ RSpec.describe KvAccessor do
33
42
  # For the expect to change, the duping is somehow necessary
34
43
  subject(:data_object) { kv_class.new(default_details.dup, default_other.dup) }
35
44
 
36
- it 'responds to all the accessor names' do
45
+ it 'responds to all the accessor names specified' do
37
46
  expect(data_object).to respond_to(:make, :year, :blue_interior, :make=,
38
47
  :year=, :blue_interior=, :model, :price,
39
48
  :color=, :price=, :upc)
40
49
  end
41
50
 
42
- it 'does not respond to unspecified accessor names' do
51
+ it 'does not respond to unspecified readers/writers' do
43
52
  expect(data_object).not_to respond_to(:submodel, :model=)
44
53
  end
45
54
 
46
- it 'has all of the corresponding reader attributes' do
55
+ it 'fetches all corresponding reader attributes' do
47
56
  expect(data_object).to have_attributes(
48
57
  make: 'Chevrolet', model: 'Camaro', blue_interior: 2_000.00,
49
58
  price: 40_000.00, year: 1967, upc: '808'
50
59
  )
51
60
  end
52
61
 
53
- it 'updates only the explicit keys on attribute assignment' do
54
- # There's some funky stuff going on with the ordering between `from()`,
55
- # `change { }`, and `expect { }`. `change { }.from` doesn't seem to compare
56
- # the objects first, before running the expect statement. I think it only
57
- # saves the initial output, runs the expect statement, runs the change block
58
- # again, and then finally compares the results. So any order dependent
59
- # results need to be another copy.
60
- expect {
62
+ describe 'attribute assignment' do
63
+ before do
61
64
  data_object.make = 'Ford'
62
65
  data_object.price = 41_000.00
63
66
  data_object.year = 1968
64
67
  data_object.blue_interior = 3_000.00
65
68
  data_object.color = 'red'
66
69
  data_object.upc = '809'
67
- }.to change { data_object.details }.from(
68
- default_details
69
- ).to(
70
- default_details.merge(
71
- :make => 'Ford', :price => 41_000.00, 'model_year' => 1968,
72
- 'color' => 'red', { 'leather' => 'blue' } => 3_000.00,
70
+ end
71
+
72
+ it 'updates the specified key-value objects' do
73
+ expect(data_object).to have_attributes(
74
+ details: default_details.merge(:make => 'Ford', :price => 41_000.00,
75
+ 'model_year' => 1968, 'color' => 'red',
76
+ { 'leather' => 'blue' } => 3_000.00),
77
+ other: { upc: '809' }
73
78
  )
74
- ).and change { data_object.other }.from(
75
- default_other
76
- ).to(upc: '809')
79
+ end
80
+
81
+ it 'all the updates are available via the attribute methods' do
82
+ expect(data_object).to have_attributes(
83
+ make: 'Ford', price: 41_000.00, year: 1968, blue_interior: 3_000.00,
84
+ upc: '809'
85
+ )
86
+ end
87
+ end
88
+
89
+ describe '.kv_accessor' do
90
+ it 'returns the hash of attributes for the kv_accessor' do
91
+ expect(
92
+ Class.new { extend KvAccessor }
93
+ .kv_accessor(:attributes, :mayonnaise, year: 'release date')
94
+ ).to eq(mayonnaise: :mayonnaise, year: 'release date')
95
+ end
96
+ end
97
+
98
+ describe '.kv_reader' do
99
+ it 'returns the hash of attributes for the kv_reader' do
100
+ expect(
101
+ Class.new { extend KvAccessor }
102
+ .kv_reader(:attributes, :iscariot, release: 'born')
103
+ ).to eq(iscariot: :iscariot, release: 'born')
104
+ end
105
+ end
106
+
107
+ describe '.kv_writer' do
108
+ it 'returns the hash of attributes for the kv_writer' do
109
+ expect(
110
+ Class.new { extend KvAccessor }
111
+ .kv_writer(:attributes, :adore, vocals: 'singers')
112
+ ).to eq(adore: :adore, vocals: 'singers')
113
+ end
77
114
  end
78
115
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kv_accessor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremiah McCann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-28 00:00:00.000000000 Z
11
+ date: 2016-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -65,3 +65,4 @@ summary: Generate accessor methods for an indexed object
65
65
  test_files:
66
66
  - spec/lib/kv_accessor_spec.rb
67
67
  - spec/spec_helper.rb
68
+ has_rdoc: