bitary 0.1.8 → 0.2.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
  SHA256:
3
- metadata.gz: 293fa51d8a5a4b4cda3a7a283737d0695b84cfcb55414afde3b9c5bb6f9688aa
4
- data.tar.gz: 6d6541faa0fed549f62a3a1b99a293ca4422511c34527a7278ea7459683f506a
3
+ metadata.gz: 23912fd76ca478d49ef1760e9d8cdb47344b3493377d00db1d133b4131c11b6e
4
+ data.tar.gz: 49def92fa2d841953139bb16cd81779d92e8f9478b6fe8a395f0400b6344a05b
5
5
  SHA512:
6
- metadata.gz: 0a81bd80568d6b5fcb20d951f0b193f98941adafd448a896f0a68ae8c97eabecca07a34a2db1d48f4e630a64d1be165ed4efe5f370bc1aabd36f78de4a5b0e7d
7
- data.tar.gz: 94f16667978d9d9be2ccf141c6539834d7f3502397db12feee83424eb0586ace151be1ca7bee960b5bc40ba0ec6e9e12c0879c74f700d1cd86c35e21f85337bb
6
+ metadata.gz: 5faafe8215df8fc28fe075a0bf8a874b503c2346489c1327ddb94f1388c12e52cc6e0218fb25a876da9d75409e58a80f369cc71bde766c325ff4d01a02353330
7
+ data.tar.gz: 0f4b3584332df720e29be0069b42979af9471152df2e4347e5cde90972902a575bba323d7040ee133a8807b918a817d95a1d65f48032ef8f27d8d8708fed7ddc
data/.rubocop.yml CHANGED
@@ -23,3 +23,11 @@ Layout/LineLength:
23
23
  Style/MixinUsage:
24
24
  Exclude:
25
25
  - 'spec/**/*.rb'
26
+
27
+ Style/ArgumentsForwarding:
28
+ Exclude:
29
+ - /**/*.rb
30
+
31
+ Naming/BlockForwarding:
32
+ Exclude:
33
+ - /**/*.rb
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [0.2.0] - 2024-04-14
2
+
3
+ - `Bitary#to_a` now returns a clone to prevent client code to misuse the data structure (same for `Bitary#each_byte`)
4
+ - Streamline the internal array initialization
5
+ - Enhance constructor implementation
6
+ - `Bitary#set` and `Bitary#set` are now suffixed by `!`
7
+
8
+ ## [0.1.9] - 2024-04-01
9
+
10
+ - boost perf even more by inlining mapping operations
11
+
12
+ ## [0.1.8] - 2024-04-01
13
+
14
+ - inline bit operations to regain original perf
15
+
1
16
  ## [0.1.7] - 2024-04-01
2
17
 
3
18
  - loads of refactoring and perf improvements
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Ruby-based implementation of the bit array data structure.
4
4
 
5
- It's still under development, but as of now, it implements simple and well-optimized logic allowing you to set, unset and retrieve bits (as well as some extra features, see below).
5
+ It implements simple and well-optimized logic allowing you to set, unset and retrieve bits (as well as some extra features, see below).
6
6
 
7
7
  ## Installation
8
8
 
@@ -20,23 +20,22 @@ $ gem install bitary
20
20
 
21
21
  ## Usage
22
22
 
23
- Documentation still needs to be written, but here is a breakdown
24
- of the main capabilities brought by the current bit array implementation:
23
+ Here is a breakdown of the main capabilities brought by the current implementation:
25
24
 
26
25
  ```ruby
27
26
  require 'bitary'
28
27
 
29
28
  bit_array_sz = Bitary.new(128) # give an explicit size. Defaults to 64 bits used per item
30
29
  bit_array_ar = Bitary.new(
31
- [255, 10, 20],
30
+ bytes: [255, 10, 20],
32
31
  bpi: Bitary::BYTE # 8 bits
33
32
  ) # create based on some integer array
34
33
 
35
34
  bit_array_sz.bpi # 64
36
35
  bit_array_ar.bpi # 8
37
36
 
38
- bit_array_ar.size # 128
39
- bit_array_ar.size # 24
37
+ bit_array_ar.bits # 128
38
+ bit_array_ar.bits # 24
40
39
 
41
40
  # set/unset/get
42
41
  bit_array_sz[23] = 1 # set bit at position 23 (0-indexed)
@@ -58,8 +57,8 @@ bit_array_ar.to_s # "01111111 00001010 00010100"
58
57
 
59
58
  # increase/decrease bits used per item
60
59
  bit_array_ar.bpi = Bitary::LONG # 64 bits
61
- bit_array_ar.to_a # [8_325_652]
62
- bit_array_ar.to_s # "0000000000000000000000000000000000000000011111110000101000010100"
60
+ bit_array_ar.to_a # [9154151182816509952]
61
+ bit_array_ar.to_s # "0111111100001010000101000000000000000000000000000000000000000000"
63
62
 
64
63
  bit_array_sz.bpi # 64
65
64
  bit_array_sz.to_a # [1_099_511_627_776, 0]
@@ -73,6 +72,14 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
73
72
 
74
73
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
75
74
 
75
+ Access the technical documentation in HTML format by issuing:
76
+
77
+ ```bash
78
+ $ bundle exec yardoc # or simply yardoc if bundler is not being used
79
+ ```
80
+
81
+ The YARD documentation will be generated under `/doc`.
82
+
76
83
  ## Contributing
77
84
 
78
85
  Bug reports and pull requests are welcome on GitHub at https://github.com/Patacode/bitary.
@@ -2,14 +2,14 @@
2
2
 
3
3
  class Bitary
4
4
  class Bitwarr
5
- attr_reader :bpi, :bitsize
5
+ attr_reader :bpi, :bits
6
6
 
7
- def initialize(initial_data, bpi: Bitary::LONG)
8
- @bitsize = init_bitsize(initial_data, bpi)
9
- @array = init_array(initial_data, @bitsize, bpi)
10
- @bpi = init_bpi(initial_data, bpi)
7
+ DEFAULT_INIT_CAP = Bitary::Size::LONG * 2
11
8
 
12
- self.bpi = bpi
9
+ def initialize(init_cap, bytes:, bpi:)
10
+ @array = init_array(init_cap, bytes, bpi)
11
+ @bits = init_bits(init_cap, bytes)
12
+ @bpi = bpi
13
13
  end
14
14
 
15
15
  def [](bit_index) = @array[item_index(bit_index)]
@@ -26,11 +26,14 @@ class Bitary
26
26
  end
27
27
 
28
28
  def to_s = @array.map { |item| to_binstr(item) }.join(' ')
29
+ def to_a = @array.clone
29
30
 
30
31
  def each_byte(&proc)
32
+ raise ArgumentError if proc.nil?
33
+
31
34
  @array.each do |item|
32
35
  explode_item(item, Bitary::BYTE, @bpi, &proc)
33
- end
36
+ end.clone
34
37
  end
35
38
 
36
39
  def bpi=(value)
@@ -40,30 +43,61 @@ class Bitary
40
43
  @bpi = value
41
44
  end
42
45
 
43
- def method_missing(method, *, &)
44
- @array.respond_to?(method) ? @array.send(method, *, &) : super
45
- end
46
+ private
46
47
 
47
- def respond_to_missing?(method, include_all = false)
48
- @array.respond_to?(method, include_all) || super
48
+ def init_bits(init_cap, bytes)
49
+ if init_cap.nil?
50
+ if bytes.nil?
51
+ DEFAULT_INIT_CAP
52
+ else
53
+ bytes.length * Bitary::BYTE
54
+ end
55
+ else
56
+ init_cap
57
+ end
49
58
  end
50
59
 
51
- private
60
+ def compute_nb_items(init_cap, bpi)
61
+ (init_cap / bpi.to_f).ceil
62
+ end
52
63
 
53
- def init_bpi(initial_data, bpi)
54
- initial_data.is_a?(Array) ? Bitary::BYTE : bpi
64
+ def init_array(init_cap, bytes, bpi)
65
+ if init_cap.nil?
66
+ if bytes.nil?
67
+ fill_array(0, DEFAULT_INIT_CAP, bpi)
68
+ else
69
+ adjust_array(bytes, bpi)
70
+ end
71
+ elsif bytes.nil?
72
+ fill_array(0, init_cap, bpi)
73
+ else
74
+ clone = adjust_array(bytes, bpi)
75
+ if init_cap > clone.length * bpi
76
+ adjust_array_to_cap(clone, init_cap, bpi)
77
+ end
78
+ clone
79
+ end
55
80
  end
56
81
 
57
- def init_bitsize(initial_data, bpi)
58
- initial_data.is_a?(Array) ? bpi * initial_data.length : initial_data
82
+ def fill_array(value, size, bpi)
83
+ [value] * compute_nb_items(size, bpi)
59
84
  end
60
85
 
61
- def init_array(initial_data, bitsize, bpi)
62
- if initial_data.is_a?(Array)
63
- initial_data.clone
86
+ def adjust_array(bytes, bpi)
87
+ if bpi == Bitary::BYTE
88
+ bytes.clone
64
89
  else
65
- [0] * (bitsize / bpi.to_f).ceil
90
+ increase_items_size(bytes, bpi, Bitary::BYTE)
91
+ end
92
+ end
93
+
94
+ def adjust_array_to_cap(bytes, init_cap, bpi)
95
+ target_size = compute_nb_items(init_cap, bpi)
96
+ while target_size > bytes.length
97
+ bytes << 0
98
+ target_size -= 1
66
99
  end
100
+ bytes
67
101
  end
68
102
 
69
103
  def item_index(bit_index)
@@ -74,21 +108,16 @@ class Bitary
74
108
  format("%0#{@bpi}d", item.to_s(2))
75
109
  end
76
110
 
77
- def operate_bit_at(operation, index)
78
- Factory
79
- .make("Handler::#{operation.capitalize}", self[index])
80
- .execute(
81
- index: index % @bpi,
82
- size: @bpi
83
- )
84
- end
85
-
86
- def operate_bit_at!(operation, index)
87
- self[index] = operate_bit_at(operation, index)
111
+ def update_items_size!(new_size)
112
+ @array = update_items_size(@array, new_size, @bpi)
88
113
  end
89
114
 
90
- def update_items_size!(value)
91
- value > @bpi ? increase_items_size!(value) : decrease_items_size!(value)
115
+ def update_items_size(array, new_size, bpi)
116
+ if new_size > bpi
117
+ increase_items_size(array, new_size, bpi)
118
+ else
119
+ decrease_items_size(array, new_size, bpi)
120
+ end
92
121
  end
93
122
 
94
123
  def append_bits(item, bpi, addend)
@@ -115,10 +144,6 @@ class Bitary
115
144
  res
116
145
  end
117
146
 
118
- def increase_items_size!(value)
119
- @array = increase_items_size(@array, value, @bpi)
120
- end
121
-
122
147
  def decrease_items_size(array, new_size, bpi)
123
148
  array.each_with_object([]) do |item, acc|
124
149
  explode_item(item, new_size, bpi) do |new_item|
@@ -127,10 +152,6 @@ class Bitary
127
152
  end
128
153
  end
129
154
 
130
- def decrease_items_size!(value)
131
- @array = decrease_items_size(@array, value, @bpi)
132
- end
133
-
134
155
  def explode_item(item, new_size, bpi)
135
156
  mask = (2**new_size) - 1
136
157
  (bpi / new_size).times do |i|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Bitary
4
- VERSION = '0.1.8'
4
+ VERSION = '0.2.0'
5
5
  end
data/lib/bitary.rb CHANGED
@@ -2,83 +2,205 @@
2
2
 
3
3
  require_relative 'bitary/size'
4
4
  require_relative 'bitary/version'
5
- require_relative 'bitary/factory'
6
5
  require_relative 'bitary/bitwarr'
7
- require_relative 'bitary/decorator'
8
- require_relative 'bitary/mapper'
9
6
 
7
+ # Bit array facade through client code SHOULD interact with.
10
8
  class Bitary
11
9
  include Size
12
10
 
13
- def initialize(initial_data, bpi: LONG)
14
- check_initial_data(initial_data)
11
+ # Creates a new bit array.
12
+ #
13
+ # If the initial bit capacity is not given (or `nil`), it will be deducted
14
+ # from the given byte array. In such case, if no byte array is given, it
15
+ # will default to {Bitwarr::DEFAULT_INIT_CAP}.
16
+ #
17
+ # If no byte array is given (or `nil`), the resulting bit array's items will
18
+ # all be set to 0.
19
+ #
20
+ # Note that, no check is performed on the byte array parameter to ensure
21
+ # that it has `Integer` items only, as it would considerably impact the
22
+ # data structure performance at initialization time. So be careful with
23
+ # it.
24
+ #
25
+ # @param init_cap [Integer?] an optional initial bit capacity
26
+ # @param bytes [Array<Integer>?] an optional byte array used to preset
27
+ # the bit array
28
+ # @param bpi [Integer] the number of bits used per item internally.
29
+ # Defaults to {LONG}
30
+ #
31
+ # @raise [TypeError] if **init_cap** is neither an `Integer` nor `nil`
32
+ # @raise [TypeError] if **bytes** is neither an `Array` nor `nil`
33
+ # @raise [TypeError] if **bpi** is not an `Integer`
34
+ # @raise [ArgumentError] if **init_cap** is <= 0
35
+ # @raise [ArgumentError] if **bpi** is not equal to one of the constants
36
+ # defined in {Size}
37
+ def initialize(init_cap = nil, bytes: nil, bpi: LONG)
38
+ check_init_cap(init_cap)
39
+ check_bytes(bytes)
15
40
  check_bpi(bpi)
16
41
 
17
- @bitwarr = Factory.make('Bitwarr', initial_data, bpi:)
42
+ @bitwarr = Bitwarr.new(init_cap, bytes:, bpi:)
18
43
  end
19
44
 
45
+ # Gets the bit at given index.
46
+ #
47
+ # @param index [Integer] the index of the bit to retrieve
48
+ #
49
+ # @raise [TypeError] if **index** is not an `Integer`
50
+ # @raise [IndexError] if **index** is < 0 || >= {#bits}
51
+ #
52
+ # @return [Integer] the bit at given index
20
53
  def [](index)
21
54
  check_bit_index(index)
22
55
 
23
56
  @bitwarr.bit_at(index)
24
57
  end
25
58
 
59
+ # Sets or unsets the bit at given index.
60
+ #
61
+ # The bit at given index will be set to 1 if given value is truthy but 0,
62
+ # or 0 otherwise.
63
+ #
64
+ # @param index [Integer] the index of the bit to set/unset
65
+ # @param value [Object] the object used to set/unset the bit at given index
66
+ #
67
+ # @raise [TypeError] if **index** is not an `Integer`
68
+ # @raise [IndexError] if **index** is < 0 || >= {#bits}
69
+ #
70
+ # @return [Object] the given **value**
26
71
  def []=(index, value)
27
72
  check_bit_index(index)
28
73
 
29
- case Factory.make('Mapper::ObjToBit').map(value)
74
+ case obj_to_bit(value)
30
75
  when 0 then @bitwarr.unbit_at!(index)
31
76
  else @bitwarr.bit_at!(index)
32
77
  end
33
78
  end
34
79
 
35
- def set(index)
80
+ # Sets the bit at given index to 1 (set).
81
+ #
82
+ # Specialization method of {#[]=} that is similar to `bitary[index] = 1`.
83
+ #
84
+ # @param index [Integer] the index of the bit to set
85
+ #
86
+ # @raise [TypeError] if **index** is not an `Integer`
87
+ # @raise [IndexError] if **index** is < 0 || >= {#bits}
88
+ #
89
+ # @return [Integer] 1
90
+ def set!(index)
36
91
  self[index] = 1
37
92
  end
38
93
 
39
- def unset(index)
94
+ # Sets the bit at given index to 0 (unset).
95
+ #
96
+ # Specialization method of {#[]=} that is similar to `bitary[index] = 0`.
97
+ #
98
+ # @param index [Integer] the index of the bit to unset
99
+ #
100
+ # @raise [TypeError] if **index** is not an `Integer`
101
+ # @raise [IndexError] if **index** is < 0 || >= {#bits}
102
+ #
103
+ # @return [Integer] 0
104
+ def unset!(index)
40
105
  self[index] = 0
41
106
  end
42
107
 
43
- def each_byte(&)
44
- @bitwarr.each_byte(&)
108
+ # Traverses each byte of this bit array starting with its byte at most
109
+ # significant address.
110
+ #
111
+ # @param block [Proc] the block to execute during byte traversal
112
+ #
113
+ # @yield [Integer] each byte of this bit array
114
+ #
115
+ # @return [Array<Integer>] a clone of the internal backed array (same
116
+ # as {#to_a})
117
+ def each_byte(&block)
118
+ @bitwarr.each_byte(&block)
45
119
  end
46
120
 
121
+ # Returns a clone of the internal backed array used by this bit array.
122
+ #
123
+ # @return [Array<Integer>] a clone of the internal backed array
47
124
  def to_a
48
125
  @bitwarr.to_a
49
126
  end
50
127
 
128
+ # Converts this bit array into an equivalent binary string.
129
+ #
130
+ # @return [String] the binary string representation of this bit array
51
131
  def to_s
52
132
  @bitwarr.to_s
53
133
  end
54
134
 
135
+ # Updates the number of bits used internally by each item.
136
+ #
137
+ # Depending on the use case, increasing/decreasing the number of bits used
138
+ # per item could reduce the memory footprint of this bit array.
139
+ #
140
+ # The idea is just to pay attention to potential internal fragmentation
141
+ # and find the right balance between the total number of bits you want to
142
+ # use and the number of bits that will be used by each item internally.
143
+ #
144
+ # @param value [Integer] the new bpi to be used by this bit array
145
+ #
146
+ # @raise [TypeError] if **value** is not an `Integer`
147
+ # @raise [ArgumentError] if **value** is not equal to one of the constants
148
+ # defined in {Size}
55
149
  def bpi=(value)
56
150
  check_bpi(value)
57
151
 
58
152
  @bitwarr.bpi = value
59
153
  end
60
154
 
61
- def size
62
- @bitwarr.bitsize
155
+ # Returns the total number of bits used by this bit array.
156
+ #
157
+ # @return [Integer] he total number of bits used by this bit array
158
+ def bits
159
+ @bitwarr.bits
63
160
  end
64
161
 
162
+ # Returns the number of bits used per item internally.
163
+ #
164
+ # @return [Integer] the number of bits used per item internally
65
165
  def bpi
66
166
  @bitwarr.bpi
67
167
  end
68
168
 
69
169
  private
70
170
 
71
- def check_initial_data(initial_data)
72
- raise ArgumentError unless [Array, Integer].include?(initial_data.class)
171
+ def check_init_cap(init_cap)
172
+ return if init_cap.nil?
173
+
174
+ raise TypeError unless init_cap.is_a?(Integer)
175
+ raise ArgumentError unless init_cap.positive?
176
+ end
177
+
178
+ def check_bytes(bytes)
179
+ return if bytes.nil?
180
+
181
+ raise TypeError unless bytes.is_a?(Array)
73
182
  end
74
183
 
75
184
  def check_bpi(bpi)
185
+ raise TypeError unless bpi.is_a?(Integer)
76
186
  raise ArgumentError unless [BYTE, SHORT, INT, LONG].include?(bpi)
77
187
  end
78
188
 
79
189
  def check_bit_index(bit_index)
80
- raise ArgumentError unless bit_index.is_a?(Integer)
81
- raise IndexError if bit_index.negative? || bit_index >= @bitwarr.bitsize
190
+ raise TypeError unless bit_index.is_a?(Integer)
191
+ raise IndexError if bit_index.negative? || bit_index >= bits
192
+ end
193
+
194
+ def obj_to_bit(value)
195
+ !!value ? truthy_to_bit(value) : 0
196
+ end
197
+
198
+ def truthy_to_bit(value)
199
+ value.is_a?(Integer) ? int_to_bit(value) : 1
200
+ end
201
+
202
+ def int_to_bit(value)
203
+ value.zero? ? 0 : 1
82
204
  end
83
205
 
84
206
  alias at []
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitary
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maximilien Ballesteros
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-01 00:00:00.000000000 Z
11
+ date: 2024-04-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby-based implementation of the bit array data structure
14
14
  email:
@@ -19,19 +19,13 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - ".rspec"
21
21
  - ".rubocop.yml"
22
+ - ".yardopts"
22
23
  - CHANGELOG.md
23
24
  - LICENSE.txt
24
25
  - README.md
25
26
  - Rakefile
26
27
  - lib/bitary.rb
27
28
  - lib/bitary/bitwarr.rb
28
- - lib/bitary/decorator.rb
29
- - lib/bitary/decorator/single_method.rb
30
- - lib/bitary/decorator/single_method/non_nil_enforcer.rb
31
- - lib/bitary/factory.rb
32
- - lib/bitary/mapper.rb
33
- - lib/bitary/mapper/int_to_bit.rb
34
- - lib/bitary/mapper/obj_to_bit.rb
35
29
  - lib/bitary/size.rb
36
30
  - lib/bitary/version.rb
37
31
  - sig/bitary.rbs
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Decorator
5
- class SingleMethod < Bitary::Decorator
6
- class NonNilEnforcer < Bitary::Decorator::SingleMethod
7
- protected
8
-
9
- def postcall(resp)
10
- (resp.nil? and raise TypeError) || resp
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'single_method/non_nil_enforcer'
4
-
5
- class Bitary
6
- class Decorator
7
- class SingleMethod < Bitary::Decorator
8
- def initialize(wrappee, method)
9
- super(wrappee) { |meth| meth == method }
10
- check_method(wrappee, method)
11
- end
12
-
13
- private
14
-
15
- def check_method(wrappee, method)
16
- raise ArgumentError unless method.is_a?(Symbol)
17
- raise NoMethodError unless wrappee.respond_to?(method)
18
- end
19
- end
20
- end
21
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'decorator/single_method'
4
-
5
- class Bitary
6
- class Decorator
7
- def initialize(wrappee, &proc)
8
- @wrappee = wrappee
9
- @predicate = proc || ->(_method) { true }
10
- end
11
-
12
- def method_missing(method, *, **, &)
13
- if @wrappee.respond_to?(method)
14
- if @predicate.call(method)
15
- args, kwargs = precall(method, *, **)
16
- resp = @wrappee.send(method, *args, **kwargs, &)
17
- postcall(resp)
18
- else
19
- @wrappee.send(method, *, **, &)
20
- end
21
- else
22
- super
23
- end
24
- end
25
-
26
- def respond_to_missing?(method, include_all = false)
27
- @wrappee.respond_to?(method, include_all) || super
28
- end
29
-
30
- def wrappee
31
- res = @wrappee
32
- res = res.wrappee while res.respond_to?(:wrappee)
33
- res
34
- end
35
-
36
- protected
37
-
38
- def precall(_method, *args, **kwargs)
39
- [args, kwargs]
40
- end
41
-
42
- def postcall(resp)
43
- resp
44
- end
45
- end
46
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Factory
5
- private_class_method :new
6
- @memo = {}
7
-
8
- def self.make(name, *, **)
9
- raise ArgumentError unless name.is_a?(String)
10
-
11
- name.split('::').reduce(Bitary) do |cls, str|
12
- cls.const_get(str)
13
- end.new(*, **)
14
- end
15
-
16
- def self.make_memo(name, *args, **kwargs)
17
- raise ArgumentError unless name.is_a?(String)
18
- if @memo.key?(name.to_sym) && !args.empty? && !kwargs.empty?
19
- raise ArgumentError
20
- end
21
-
22
- @memo[name.to_sym] ||= make(name, *args, **kwargs)
23
- end
24
- end
25
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Mapper
5
- class IntToBit < Bitary::Mapper
6
- def map(value)
7
- if value.is_a?(Integer)
8
- value.zero? ? 0 : 1
9
- else
10
- 1
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Bitary
4
- class Mapper
5
- class ObjToBit < Bitary::Mapper
6
- def map(value)
7
- case !!value
8
- when true then IntToBit.new.map(value)
9
- when false then 0
10
- end
11
- end
12
- end
13
- end
14
- end
data/lib/bitary/mapper.rb DELETED
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'mapper/int_to_bit'
4
- require_relative 'mapper/obj_to_bit'
5
-
6
- class Bitary
7
- class Mapper
8
- def self.new(*arg, **kwargs)
9
- Decorator::SingleMethod::NonNilEnforcer.new(super, :map)
10
- end
11
-
12
- def map(value)
13
- raise NotImplementedError
14
- end
15
- end
16
- end