attr_bitwise 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +4 -1
- data/README.md +228 -34
- data/circle.yml +3 -0
- data/lib/attr_bitwise/version.rb +1 -1
- data/lib/attr_bitwise.rb +21 -7
- data/spec/attr_bitwise_spec.rb +58 -38
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0fe35e1015d6b3d56fad87e17480767740a23dd0
|
4
|
+
data.tar.gz: c0ca410c937a40d73eab1b8dac53087cd93c4ab2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddb05f9230a5a78c3f4534422eb8ec36c1ccabea059ce52a0b8fbc03456e468e59a64c3c7104afe9adfc5134c339223d94042d980d9e958359ed27fe96065927
|
7
|
+
data.tar.gz: 29bc9ace8d2e82f5459802ebd7e69d3a4978ef9712b6814a6742de4bd0606f0e78a1a2d2fdf3841aa2cd141dbda74646ba6baf9e106c977ac85a363ca353311f
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,36 +1,12 @@
|
|
1
|
-
# `attr_bitwise`
|
1
|
+
# `attr_bitwise` ![https://circleci.com/gh/wittydeveloper/attr_bitwise.png?circle-token=7f58370c3b13faaf1954b9e8fe6c7b1fb329daf2](https://circleci.com/gh/wittydeveloper/attr_bitwise.png?circle-token=7f58370c3b13faaf1954b9e8fe6c7b1fb329daf2) [![Gem Version](https://badge.fury.io/rb/attr_bitwise.svg)](https://badge.fury.io/rb/attr_bitwise)
|
2
2
|
Bitwise attribute for ruby class and Rails model
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
# attr_bitwise :<name>, [column_name: <column_name>,] mapping: <values_sym>
|
11
|
-
#
|
12
|
-
# Example
|
13
|
-
# class MyModel < ActiveRecord::Base
|
14
|
-
# include BitwiseUtils
|
15
|
-
#
|
16
|
-
# attr_bitwise :payment_types, mapping: [:slots, :credits]
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# Will define the following high-level methods :
|
20
|
-
# - Class#payment_types => [<Symbol>, ...]
|
21
|
-
# - Class#payment_type?(value_or_sym) => Boolean
|
22
|
-
# - Class#add_payment_type(value_or_sym) => Fixnum
|
23
|
-
# - Class#remove_payment_type(value_or_sym) => Fixnum
|
24
|
-
#
|
25
|
-
# Will define the following low-level methods :
|
26
|
-
# - Class.to_bitwise_values(object, name) => [<Fixnum>, ...]
|
27
|
-
# - Class#payment_types_union([Fixnum, ..]) => [Fixnum, ..]
|
28
|
-
# - Class.bitwise_union([Fixnum, ..], name) => [Fixnum, ..]
|
29
|
-
# - Class#payment_types_intersection([Fixnum, ..]) => [Fixnum, ..]
|
30
|
-
# - Class.bitwise_intersection([Fixnum, ..], name) => [Fixnum, ..]
|
31
|
-
# - Class#payment_types_mapping => Hash
|
32
|
-
#
|
33
|
-
```
|
4
|
+
## Features
|
5
|
+
|
6
|
+
- bitwise attribute + helpers, useful for storing multiple states in one place
|
7
|
+
- ActiveRecord compatible
|
8
|
+
|
9
|
+
[Please read this article for some concrete examples](https://medium.com/jobteaser-dev-team/rails-bitwise-enum-with-super-powers-5030bda5dbab)
|
34
10
|
|
35
11
|
|
36
12
|
## Install
|
@@ -38,12 +14,230 @@ Bitwise attribute for ruby class and Rails model
|
|
38
14
|
|
39
15
|
### Inline
|
40
16
|
|
41
|
-
- `gem install
|
17
|
+
- `gem install attr_bitwise`
|
42
18
|
|
43
19
|
### Gemfile
|
44
20
|
|
45
|
-
- `gem '
|
21
|
+
- `gem 'attr_bitwise'`
|
22
|
+
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
attr_bitwise :<name>, mapping: <values_sym> [, column_name: <column_name>]
|
28
|
+
```
|
29
|
+
|
30
|
+
## Example
|
31
|
+
|
32
|
+
You have a website with many locales (English, French, German...) with specific content in each locale. You want your users to be able to chose which content they want to see and you want to be able to query the users by the locales they have choosen.
|
33
|
+
|
34
|
+
Start with migration
|
35
|
+
```ruby
|
36
|
+
class CreateUsers < ActiveRecord::Migration
|
37
|
+
def change
|
38
|
+
create_table :users do |t|
|
39
|
+
# [...]
|
40
|
+
t.integer :locales_value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Model
|
47
|
+
```ruby
|
48
|
+
|
49
|
+
class User < ActiveRecord::Base
|
50
|
+
include AttrBitwise
|
51
|
+
|
52
|
+
attr_bitwise :locales, mapping: [:en, :fr, :de]
|
53
|
+
|
54
|
+
scope :with_any_locales, lambda { |*locales_sym|
|
55
|
+
where(locales_value: bitwise_union(*locales_sym, 'locales'))
|
56
|
+
}
|
57
|
+
|
58
|
+
scope :with_all_locales, lambda { |*locales_sym|
|
59
|
+
where(locales_value: bitwise_intersection(*locales_sym, 'locales'))
|
60
|
+
}
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
###
|
65
|
+
|
66
|
+
# return all users who can see at least english or french content
|
67
|
+
User.with_any_locales(:en, :fr)
|
68
|
+
|
69
|
+
# return all users who can see english and french content
|
70
|
+
User.with_all_locales(:en, :fr)
|
71
|
+
|
72
|
+
```
|
73
|
+
|
74
|
+
|
75
|
+
## API
|
76
|
+
|
77
|
+
**Examples with <code>name = 'locales'</code>**
|
78
|
+
|
79
|
+
### High level methods
|
80
|
+
<table>
|
81
|
+
<tr>
|
82
|
+
<th>Method</th>
|
83
|
+
<th>Return</th>
|
84
|
+
<th>Description</th>
|
85
|
+
</tr>
|
86
|
+
<tr>
|
87
|
+
<td>
|
88
|
+
<code>Class#locales</code>
|
89
|
+
</td>
|
90
|
+
<td>
|
91
|
+
<code>[<Symbol>, ...]</code>
|
92
|
+
</td>
|
93
|
+
<td>
|
94
|
+
Return values as symbols
|
95
|
+
</td>
|
96
|
+
</tr>
|
97
|
+
<tr>
|
98
|
+
<td>
|
99
|
+
<code>Class#locales=([value_or_sym, ..])</code>
|
100
|
+
</td>
|
101
|
+
<td>
|
102
|
+
<code>[<Symbol>, ...]</code>
|
103
|
+
</td>
|
104
|
+
<td>
|
105
|
+
Given an array of values (Fixnum or Symbol) or single value (Fixnum or Symbol) add them to value.
|
106
|
+
</td>
|
107
|
+
</tr>
|
108
|
+
<tr>
|
109
|
+
<td>
|
110
|
+
<code>Class#locale == fixnum_or_sym</code>
|
111
|
+
</td>
|
112
|
+
<td>
|
113
|
+
<code>Boolean</code>
|
114
|
+
</td>
|
115
|
+
<td>
|
116
|
+
Return true if value contains only Fixnum or Symbol
|
117
|
+
</td>
|
118
|
+
</tr>
|
119
|
+
<tr>
|
120
|
+
<td>
|
121
|
+
<code>Class#locale?(fixnum_or_sym)</code>
|
122
|
+
</td>
|
123
|
+
<td>
|
124
|
+
<code>Boolean</code>
|
125
|
+
</td>
|
126
|
+
<td>
|
127
|
+
Return true if value contains Fixnum or Symbol
|
128
|
+
</td>
|
129
|
+
</tr>
|
130
|
+
<tr>
|
131
|
+
<td>
|
132
|
+
<code>Class#add_locale(value_or_sym)</code>
|
133
|
+
</td>
|
134
|
+
<td>
|
135
|
+
<code>Fixnum</code>
|
136
|
+
</td>
|
137
|
+
<td>
|
138
|
+
Add Fixnum or Symbol to value
|
139
|
+
</td>
|
140
|
+
</tr>
|
141
|
+
<tr>
|
142
|
+
<td>
|
143
|
+
<code>Class#remove_locale(value_or_sym)</code>
|
144
|
+
</td>
|
145
|
+
<td>
|
146
|
+
<code>Fixnum</code>
|
147
|
+
</td>
|
148
|
+
<td>
|
149
|
+
Remove Fixnum or Symbol to value
|
150
|
+
</td>
|
151
|
+
</tr>
|
152
|
+
<tr>
|
153
|
+
<td>
|
154
|
+
<code>Class#locales_union([value_or_sym, ..])</code>
|
155
|
+
</td>
|
156
|
+
<td>
|
157
|
+
<code>[Fixnum, ..]</code>
|
158
|
+
</td>
|
159
|
+
<td>
|
160
|
+
Given an array of values (Fixnum or Symbol), return bitwise union computation <br>
|
161
|
+
Return all possible values (mask) for an union of given values
|
162
|
+
</td>
|
163
|
+
</tr>
|
164
|
+
<tr>
|
165
|
+
<td>
|
166
|
+
<code>Class#locales_intersection([value_or_sym, ..])</code>
|
167
|
+
</td>
|
168
|
+
<td>
|
169
|
+
<code>[Fixnum, ..]</code>
|
170
|
+
</td>
|
171
|
+
<td>
|
172
|
+
Given an array of values (Fixnum or Symbol), return bitwise intersection computation <br>
|
173
|
+
Return all possible values (mask) for an intersection of given values
|
174
|
+
</td>
|
175
|
+
</tr>
|
176
|
+
<tr>
|
177
|
+
<td>
|
178
|
+
<code>Class#locales_mapping</code>
|
179
|
+
</td>
|
180
|
+
<td>
|
181
|
+
<code>Hash</code>
|
182
|
+
</td>
|
183
|
+
<td>
|
184
|
+
Return <code>Symbol</code> -> <code>Fixnum</code> mapping
|
185
|
+
</td>
|
186
|
+
</tr>
|
187
|
+
|
188
|
+
|
189
|
+
</table>
|
190
|
+
|
191
|
+
|
192
|
+
### Low level methods
|
193
|
+
|
194
|
+
*Theses methods are static, so a <code>name</code> parameters is mandatory in order to fetch mapping*
|
195
|
+
|
196
|
+
|
197
|
+
<table>
|
198
|
+
<tr>
|
199
|
+
<th>Method</th>
|
200
|
+
<th>Return</th>
|
201
|
+
<th>Description</th>
|
202
|
+
</tr>
|
203
|
+
<tr>
|
204
|
+
<td>
|
205
|
+
<code>Class.to_bitwise_values(object, name)</code>
|
206
|
+
</td>
|
207
|
+
<td>
|
208
|
+
<code>[Fixnum, ...]</code>
|
209
|
+
</td>
|
210
|
+
<td>
|
211
|
+
Given an Object and a attribute name, return Fixnum value depending on mapping
|
212
|
+
</td>
|
213
|
+
</tr>
|
214
|
+
<tr>
|
215
|
+
<td>
|
216
|
+
<code>Class.bitwise_union([Fixnum, ..], name)</code>
|
217
|
+
</td>
|
218
|
+
<td>
|
219
|
+
<code>[Fixnum, ..]</code>
|
220
|
+
</td>
|
221
|
+
<td>
|
222
|
+
Given an array of values (Fixnum or Symbol) and a attribute name, return bitwise union computation <br>
|
223
|
+
Return all possible values (mask) for an union of given values
|
224
|
+
</td>
|
225
|
+
</tr>
|
226
|
+
<tr>
|
227
|
+
<td>
|
228
|
+
<code>Class.bitwise_intersection([Fixnum, ..], name)</code>
|
229
|
+
</td>
|
230
|
+
<td>
|
231
|
+
<code>[Fixnum, ..]</code>
|
232
|
+
</td>
|
233
|
+
<td>
|
234
|
+
Given an array of values (Fixnum or Symbol) and a attribute name, return bitwise intersection computation <br>
|
235
|
+
Return all possible values (mask) for an intersection of given values
|
236
|
+
</td>
|
237
|
+
</tr>
|
238
|
+
|
239
|
+
</table>
|
46
240
|
|
47
241
|
|
48
242
|
----------------------------------------
|
49
|
-
Maintainers : @wittydeveloper and @FSevaistre
|
243
|
+
Maintainers : [@wittydeveloper](https://github.com/wittydeveloper) and [@FSevaistre](https://github.com/FSevaistre)
|
data/circle.yml
ADDED
data/lib/attr_bitwise/version.rb
CHANGED
data/lib/attr_bitwise.rb
CHANGED
@@ -12,7 +12,7 @@ require "attr_bitwise/version"
|
|
12
12
|
#
|
13
13
|
# Example
|
14
14
|
# class MyModel < ActiveRecord::Base
|
15
|
-
# include
|
15
|
+
# include AttrBitwise
|
16
16
|
#
|
17
17
|
# attr_bitwise :payment_types, mapping: [:slots, :credits]
|
18
18
|
# end
|
@@ -35,6 +35,21 @@ require "attr_bitwise/version"
|
|
35
35
|
module AttrBitwise
|
36
36
|
extend ActiveSupport::Concern
|
37
37
|
|
38
|
+
|
39
|
+
# Custom class that allow to use shortcut :
|
40
|
+
# my_column == :banana
|
41
|
+
# instead of
|
42
|
+
# my_column == [:banana]
|
43
|
+
class ComparableSymbolsArray < Array
|
44
|
+
def ==(other_object)
|
45
|
+
if other_object.is_a?(Symbol)
|
46
|
+
self.size == 1 && self.first == other_object
|
47
|
+
else
|
48
|
+
super(other_object)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
38
53
|
# ClassMethods
|
39
54
|
module ClassMethods
|
40
55
|
######################
|
@@ -59,10 +74,7 @@ module AttrBitwise
|
|
59
74
|
define_method("#{name}") { send(:value_getter, bitwise_mapping) }
|
60
75
|
|
61
76
|
define_method("#{name}=") do |values_or_symbols_array|
|
62
|
-
|
63
|
-
values_or_symbols_array = [values_or_symbols_array]
|
64
|
-
end
|
65
|
-
send(:value_setter, values_or_symbols_array, bitwise_mapping)
|
77
|
+
send(:value_setter, Array(values_or_symbols_array), bitwise_mapping)
|
66
78
|
end
|
67
79
|
|
68
80
|
# masks symbol presence
|
@@ -199,8 +211,10 @@ module AttrBitwise
|
|
199
211
|
# Return current value to symbols array
|
200
212
|
# Ex : 011 => :slots, :credits
|
201
213
|
def value_getter(mapping)
|
202
|
-
|
203
|
-
|
214
|
+
ComparableSymbolsArray.new(
|
215
|
+
mapping.values.select { |pv| (value & pv) != 0 }.
|
216
|
+
map { |v| value_to_sym(v, mapping) }
|
217
|
+
)
|
204
218
|
end
|
205
219
|
|
206
220
|
# Set current values from values array
|
data/spec/attr_bitwise_spec.rb
CHANGED
@@ -7,12 +7,12 @@ describe AttrBitwise do
|
|
7
7
|
|
8
8
|
include AttrBitwise
|
9
9
|
|
10
|
-
attr_accessor :
|
10
|
+
attr_accessor :fruits_value
|
11
11
|
|
12
|
-
attr_bitwise :
|
12
|
+
attr_bitwise :fruits, mapping: [:banana, :apple]
|
13
13
|
|
14
14
|
def initialize
|
15
|
-
@
|
15
|
+
@fruits_value = 0
|
16
16
|
end
|
17
17
|
|
18
18
|
end
|
@@ -26,10 +26,10 @@ describe AttrBitwise do
|
|
26
26
|
expect(
|
27
27
|
TestClass.to_bitwise_values(
|
28
28
|
{
|
29
|
-
a: :
|
30
|
-
b: :
|
29
|
+
a: :apple,
|
30
|
+
b: :banana
|
31
31
|
},
|
32
|
-
'
|
32
|
+
'fruits'
|
33
33
|
)
|
34
34
|
).to eq [2, 1]
|
35
35
|
end
|
@@ -38,101 +38,121 @@ describe AttrBitwise do
|
|
38
38
|
context 'with Array argument' do
|
39
39
|
it do
|
40
40
|
expect(TestClass.to_bitwise_values(
|
41
|
-
[:
|
42
|
-
'
|
41
|
+
[:apple, :banana],
|
42
|
+
'fruits'
|
43
43
|
)).to eq [2, 1]
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
47
|
context 'with Fixnum argument' do
|
48
48
|
it do
|
49
|
-
expect(TestClass.to_bitwise_values(1, '
|
49
|
+
expect(TestClass.to_bitwise_values(1, 'fruits')).to eq 1
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
53
|
end
|
54
54
|
|
55
|
-
context 'with `
|
55
|
+
context 'with `fruits` attribute_name' do
|
56
56
|
|
57
|
-
context '#
|
57
|
+
context '#fruits=' do
|
58
58
|
|
59
|
-
before { subject.
|
59
|
+
before { subject.fruits = [:banana, :apple] }
|
60
60
|
|
61
61
|
it 'should set proper value' do
|
62
|
-
expect(subject.
|
63
|
-
expect(subject.
|
62
|
+
expect(subject.fruits_value).to eq 3
|
63
|
+
expect(subject.fruits).to eq [:banana, :apple]
|
64
64
|
end
|
65
65
|
|
66
66
|
end
|
67
67
|
|
68
|
-
context '
|
69
|
-
|
68
|
+
context '#fruits==' do
|
69
|
+
|
70
|
+
context 'when value is incorrect' do
|
71
|
+
before { subject.fruits = [:banana, :apple] }
|
72
|
+
|
73
|
+
it do
|
74
|
+
expect(subject.fruits == :banana).to eq false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when value is correct' do
|
79
|
+
before { subject.fruits = [:banana] }
|
80
|
+
|
81
|
+
it do
|
82
|
+
expect(subject.fruits == :banana).to eq true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'with `fruits_value` = 0' do
|
89
|
+
context '#fruits' do
|
70
90
|
|
71
91
|
it do
|
72
|
-
expect(subject.
|
92
|
+
expect(subject.fruits).to eq []
|
73
93
|
end
|
74
94
|
|
75
95
|
end
|
76
96
|
|
77
|
-
context '#
|
97
|
+
context '#add_fruit' do
|
78
98
|
|
79
99
|
it do
|
80
|
-
subject.
|
81
|
-
expect(subject.
|
100
|
+
subject.add_fruit(:banana)
|
101
|
+
expect(subject.fruits).to eq [:banana]
|
82
102
|
end
|
83
103
|
|
84
104
|
context 'when called twice, each type remains unique' do
|
85
105
|
it do
|
86
|
-
subject.
|
87
|
-
subject.
|
88
|
-
expect(subject.
|
106
|
+
subject.add_fruit(:banana)
|
107
|
+
subject.add_fruit(:banana)
|
108
|
+
expect(subject.fruits).to eq [:banana]
|
89
109
|
end
|
90
110
|
end
|
91
111
|
|
92
112
|
end
|
93
113
|
|
94
|
-
context '#
|
114
|
+
context '#fruit?(:banana)' do
|
95
115
|
|
96
116
|
it do
|
97
|
-
expect(subject.
|
117
|
+
expect(subject.fruit?(:banana)).to eq false
|
98
118
|
end
|
99
119
|
|
100
120
|
end
|
101
121
|
end
|
102
122
|
|
103
|
-
context 'with `
|
123
|
+
context 'with `fruits_value` = 3' do
|
104
124
|
|
105
|
-
before { subject.
|
125
|
+
before { subject.fruits_value = 3 }
|
106
126
|
|
107
|
-
context '#
|
127
|
+
context '#fruits' do
|
108
128
|
|
109
129
|
it do
|
110
|
-
expect(subject.
|
130
|
+
expect(subject.fruits).to eq [:banana, :apple]
|
111
131
|
end
|
112
132
|
|
113
133
|
end
|
114
134
|
|
115
|
-
context '#
|
135
|
+
context '#fruit?(:banana)' do
|
116
136
|
|
117
137
|
it do
|
118
|
-
expect(subject.
|
138
|
+
expect(subject.fruit?(:banana)).to eq true
|
119
139
|
end
|
120
140
|
|
121
141
|
end
|
122
142
|
|
123
|
-
context '#
|
143
|
+
context '#remove_fruit' do
|
124
144
|
|
125
145
|
it do
|
126
|
-
subject.
|
127
|
-
expect(subject.
|
146
|
+
subject.remove_fruit(:banana)
|
147
|
+
expect(subject.fruits).to eq [:apple]
|
128
148
|
end
|
129
149
|
|
130
150
|
end
|
131
151
|
|
132
|
-
context '#
|
152
|
+
context '#fruits_union' do
|
133
153
|
|
134
154
|
it do
|
135
|
-
expect(subject.
|
155
|
+
expect(subject.fruits_union(1, 2)).to eq [1, 3, 2]
|
136
156
|
end
|
137
157
|
|
138
158
|
end
|
@@ -141,7 +161,7 @@ describe AttrBitwise do
|
|
141
161
|
|
142
162
|
it do
|
143
163
|
expect(
|
144
|
-
TestClass.bitwise_union(1, 2, '
|
164
|
+
TestClass.bitwise_union(1, 2, 'fruits')
|
145
165
|
).to eq [1, 3, 2]
|
146
166
|
end
|
147
167
|
|
@@ -151,7 +171,7 @@ describe AttrBitwise do
|
|
151
171
|
|
152
172
|
it do
|
153
173
|
expect(
|
154
|
-
TestClass.bitwise_intersection(1, 2, '
|
174
|
+
TestClass.bitwise_intersection(1, 2, 'fruits')
|
155
175
|
).to eq [3]
|
156
176
|
end
|
157
177
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_bitwise
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charly POLY
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- README.md
|
81
81
|
- Rakefile
|
82
82
|
- attr_bitwise.gemspec
|
83
|
+
- circle.yml
|
83
84
|
- lib/attr_bitwise.rb
|
84
85
|
- lib/attr_bitwise/version.rb
|
85
86
|
- spec/attr_bitwise_spec.rb
|
@@ -103,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
104
|
version: '0'
|
104
105
|
requirements: []
|
105
106
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.
|
107
|
+
rubygems_version: 2.4.8
|
107
108
|
signing_key:
|
108
109
|
specification_version: 4
|
109
110
|
summary: Bitwise attribute for ruby class and Rails model
|