bases 1.0.0
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 +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +22 -0
- data/.travis.yml +6 -0
- data/.yardopts +1 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +174 -0
- data/Rakefile +9 -0
- data/bases.gemspec +31 -0
- data/lib/bases.rb +24 -0
- data/lib/bases/algorithms.rb +43 -0
- data/lib/bases/constants.rb +32 -0
- data/lib/bases/helpers.rb +39 -0
- data/lib/bases/monkeypatches.rb +6 -0
- data/lib/bases/monkeypatches/array.rb +29 -0
- data/lib/bases/monkeypatches/integer.rb +26 -0
- data/lib/bases/monkeypatches/string.rb +29 -0
- data/lib/bases/number.rb +164 -0
- data/lib/bases/version.rb +6 -0
- data/test/helpers_test.rb +34 -0
- data/test/misc_test.rb +32 -0
- data/test/monkeypatches_test.rb +46 -0
- data/test/number_test.rb +138 -0
- data/test/test_helper.rb +13 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 902a4986a5074750b2a81f17eaccb1e8bd944e3d
|
4
|
+
data.tar.gz: d639c6bb2b3b3f71f1a42dd009f046d2fe5bf721
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5377cb3c5ef10f7a28854c42f373cb3afbb43ad9b9c1e09a4f337607bec6c6d6c769e3979300b0eab1f7a8427cb87674637418da8ed02c65aac1f984e6d3db32
|
7
|
+
data.tar.gz: 9ec434e817b7563702b584c64f619a06000c410c5343744f8460786bf20f719b447346f482263e5277ea5e69f2b4299b30b577dbff75fba4915a9620512b7ca0
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --private
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Andrea Leopardi
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
# Bases
|
2
|
+
|
3
|
+
[](https://travis-ci.org/whatyouhide/bases)
|
4
|
+
[](http://badge.fury.io/rb/bases)
|
5
|
+
[](https://coveralls.io/r/whatyouhide/bases)
|
6
|
+
[](https://codeclimate.com/github/whatyouhide/bases)
|
7
|
+
[](https://gemnasium.com/whatyouhide/bases)
|
8
|
+
[](http://inch-ci.org/github/whatyouhide/bases)
|
9
|
+
|
10
|
+
Convert **from** and **to** any base you can think of.
|
11
|
+
|
12
|
+
A bunch of features:
|
13
|
+
|
14
|
+
* Convert to bases up to **whatever you want!**
|
15
|
+
* Use custom bases defined as arrays, like this binary base: `['↑', '↓']`.
|
16
|
+
* Use multicharacter digits.
|
17
|
+
* Use **emojis** as digits!
|
18
|
+
* Fall back to Ruby's `Integer#to_s` and `String#to_i` when the base is less
|
19
|
+
than 36.
|
20
|
+
* Superdocumented, tested like shuttle launches were depending on it (this may
|
21
|
+
not be true).
|
22
|
+
* Supports MRI Ruby (yeah, just Ruby) from version 1.9.3.
|
23
|
+
|
24
|
+
|
25
|
+
## Why
|
26
|
+
|
27
|
+
Ruby can convert bases, but only with bases up to 36. But converting to bigger
|
28
|
+
basis is just as fun (if not even more!), since you can easily reduce the number
|
29
|
+
of character used to represent a number.
|
30
|
+
|
31
|
+
I only know of gem that does this, [radix][radix]. Radix isn't bad, but I don't
|
32
|
+
like it because it monkeypatches everything. It provides the `b`
|
33
|
+
method on strings, which on recent versions of Ruby is also a [default
|
34
|
+
method][ruby-string-b].
|
35
|
+
|
36
|
+
|
37
|
+
## Installation
|
38
|
+
|
39
|
+
Add this line to your application's Gemfile:
|
40
|
+
|
41
|
+
``` ruby
|
42
|
+
gem 'bases'
|
43
|
+
```
|
44
|
+
|
45
|
+
And then execute:
|
46
|
+
|
47
|
+
```
|
48
|
+
$ bundle
|
49
|
+
```
|
50
|
+
|
51
|
+
Or install it yourself as:
|
52
|
+
|
53
|
+
``` bash
|
54
|
+
$ gem install bases
|
55
|
+
```
|
56
|
+
|
57
|
+
|
58
|
+
## Usage
|
59
|
+
|
60
|
+
The main hub for the usage of this gem is the `Bases.val` method.
|
61
|
+
It takes a parameter that can be a bunch of things.
|
62
|
+
|
63
|
+
* An integer: in this case, the source base is assumed to be the decimal base.
|
64
|
+
* An array: no base is assumed, you have to manually specify it (keep reading!).
|
65
|
+
The array is assumed to be a list of digits (each element is a digit) from
|
66
|
+
the most significant one to the least significant one, like you'd expect.
|
67
|
+
* A string: no base is assumed. If the string doesn't contain whitespace, each
|
68
|
+
character is assumed to be a digit; otherwise, whitespace is assumed to
|
69
|
+
separate multicharacter digits (wow, multicharacter digits!).
|
70
|
+
|
71
|
+
The return value of `Bases.val` is junk (sort of), so you want to
|
72
|
+
call some methods to specify a *source base* and a *destination base*.
|
73
|
+
|
74
|
+
Those methods are the `in_base` and `to_base` methods:
|
75
|
+
|
76
|
+
``` ruby
|
77
|
+
Bases.val('100').in_base(2).to_base(10) #=> '4'
|
78
|
+
Bases.val('1111').in_base(2).to_base(16) #=> 'f'
|
79
|
+
Bases.val('A').in_base(16).to_base(10) #=> '10'
|
80
|
+
```
|
81
|
+
|
82
|
+
The `to_base` method always returns a `String`, even with `to_base(10)`. To
|
83
|
+
overcome that, just call `to_i` on the string.
|
84
|
+
|
85
|
+
When you pass an integer to `val`, base 10 is assumed:
|
86
|
+
|
87
|
+
``` ruby
|
88
|
+
Bases.val(10).to_base(Bases::HEX) #=> 'A'
|
89
|
+
Bases.val(0b1011).to_base(2) #=> '1011'
|
90
|
+
```
|
91
|
+
|
92
|
+
#### Bracket syntax
|
93
|
+
|
94
|
+
`Bases.val` is aliased to `Bases.[]`, so that you can
|
95
|
+
easily create values with a clean syntax:
|
96
|
+
|
97
|
+
``` ruby
|
98
|
+
Bases[5].to_base(2) #=> '101'
|
99
|
+
```
|
100
|
+
|
101
|
+
#### Array bases
|
102
|
+
|
103
|
+
You can use arrays everywhere you can use a base. The elements of the array will
|
104
|
+
be the digits of the new base, from left to right. Defining a base through an
|
105
|
+
array is easy:
|
106
|
+
|
107
|
+
``` ruby
|
108
|
+
# An alternative way of defining base 2:
|
109
|
+
base2 = [0, 1]
|
110
|
+
|
111
|
+
# A very cool alternative binary base:
|
112
|
+
christmas_star_base = %w(+ ≈)
|
113
|
+
|
114
|
+
# A (contrived) example of base64:
|
115
|
+
base64 = ('A'..'Z').to_a + ('a'..'z').to_a + (0..9).to_a + %w(+ /)
|
116
|
+
```
|
117
|
+
|
118
|
+
#### Predefined bases
|
119
|
+
|
120
|
+
Some default (common) bases are offered as constants:
|
121
|
+
|
122
|
+
``` ruby
|
123
|
+
Bases::B62 #=> base 62 (alphanumeric)
|
124
|
+
Bases::B64 #=> base64
|
125
|
+
```
|
126
|
+
|
127
|
+
#### Common bases
|
128
|
+
|
129
|
+
The gem provides a bunch of methods for dealing with common bases. These methods
|
130
|
+
should be used in place of the `in_base` and `to_base` methods.
|
131
|
+
|
132
|
+
They are:
|
133
|
+
|
134
|
+
- `in_binary`/`to_binary`
|
135
|
+
- `in_hex`/`to_hex` (`in_hex` solves the issue noted in the [hexadecimal base
|
136
|
+
section](#hex))
|
137
|
+
|
138
|
+
Since the decimal is also common, a `to_i` method is included. This method
|
139
|
+
returns an integer, not a string, in order to conform with the Ruby standard
|
140
|
+
library.
|
141
|
+
|
142
|
+
``` ruby
|
143
|
+
Bases.val('1010').in_binary.to_i #=> 10
|
144
|
+
```
|
145
|
+
|
146
|
+
### Monkeypatching
|
147
|
+
|
148
|
+
I can see the appeal of monkeypatching (can I?). So, you can specifically
|
149
|
+
require to monkeypatch the `Integer`, `Array` and `String` Ruby classes:
|
150
|
+
|
151
|
+
``` ruby
|
152
|
+
# Instead of just 'bases':
|
153
|
+
require 'bases/monkeypatches'
|
154
|
+
|
155
|
+
2.to_base [:a, :b] #=> 'ba'
|
156
|
+
10.to_binary #=> '1010'
|
157
|
+
15.to_hex #=> 'f'
|
158
|
+
|
159
|
+
'A'.in_hex.to_i #=> 10
|
160
|
+
'baba'.in_base([:a, :b]).to_base(2) #=> '1010'
|
161
|
+
|
162
|
+
['foo', 'bar'].in_base(['foo', 'bar', 'baz']).to_i #=> 1
|
163
|
+
```
|
164
|
+
|
165
|
+
|
166
|
+
## Contributing
|
167
|
+
|
168
|
+
Fork, make changes, commit those changes, push to your fork, create a new Pull
|
169
|
+
Request here. Thanks!
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
[radix]: https://github.com/rubyworks/radix
|
174
|
+
[ruby-string-b]: http://www.ruby-doc.org/core-2.1.3/String.html#method-i-b
|
data/Rakefile
ADDED
data/bases.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bases/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'bases'
|
8
|
+
spec.version = Bases::VERSION
|
9
|
+
spec.authors = ['Andrea Leopardi']
|
10
|
+
spec.email = 'an.leopardi@gmail.com'
|
11
|
+
spec.summary = 'Convert bases like a mofo.'
|
12
|
+
spec.homepage = 'https://github.com/whatyouhide/bases'
|
13
|
+
spec.license = 'MIT'
|
14
|
+
spec.description = <<-DESC
|
15
|
+
This gem lets you convert integers from and to whatever base you like. You
|
16
|
+
can use array bases where you specify all the digits in the base,
|
17
|
+
multicharacter digits and other niceties. By default, this gem avoids
|
18
|
+
monkeypatching core Ruby classes, but it can be configured to monkeypatch
|
19
|
+
too.
|
20
|
+
DESC
|
21
|
+
|
22
|
+
spec.files = `git ls-files -z`.split("\x0")
|
23
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10'
|
28
|
+
spec.add_development_dependency 'minitest', '~> 5'
|
29
|
+
spec.add_development_dependency 'minitest-reporters', '~> 1.0'
|
30
|
+
spec.add_development_dependency 'coveralls', '~> 0.7'
|
31
|
+
end
|
data/lib/bases.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Constants
|
4
|
+
require 'bases/version'
|
5
|
+
require 'bases/constants'
|
6
|
+
# Modules
|
7
|
+
require 'bases/helpers'
|
8
|
+
require 'bases/algorithms'
|
9
|
+
# Classes
|
10
|
+
require 'bases/number'
|
11
|
+
|
12
|
+
# The main module.
|
13
|
+
module Bases
|
14
|
+
# Create a new instance of `Number` from `value`.
|
15
|
+
# @param [String|Integer] value A value as in `Number.new`
|
16
|
+
# @return [Number]
|
17
|
+
def self.val(value)
|
18
|
+
Bases::Number.new(value)
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
alias_method :[], :val
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# This module encapsulates the practical algorithms used to change bases.
|
4
|
+
module Bases::Algorithms
|
5
|
+
# The common base conversion algorithm, which converts a number in base 10
|
6
|
+
# (`value`) to its value in base `new_base`.
|
7
|
+
# @param [Integer] value The value in base 10
|
8
|
+
# @param [Array<String>] new_base
|
9
|
+
# @return [Array<String>] An array of digits (as strings) from the most
|
10
|
+
# significant to the least significant one
|
11
|
+
def self.convert_to_base(value, new_base)
|
12
|
+
# Return early if the is 0, as it is the first digit of the base array.
|
13
|
+
return [new_base.first] if value == 0
|
14
|
+
|
15
|
+
result = []
|
16
|
+
numeric_base = new_base.count
|
17
|
+
|
18
|
+
while value > 0
|
19
|
+
remainder = value % numeric_base
|
20
|
+
value /= numeric_base
|
21
|
+
result.unshift(new_base[remainder])
|
22
|
+
end
|
23
|
+
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
# Convert a value in a source base to an integer in base 10.
|
28
|
+
# @param [Array<String>] digits_ary An array of digits, from the most
|
29
|
+
# significant to the least significant.
|
30
|
+
# @param [Array<String>] source_base A base expressed as a list of digits
|
31
|
+
# @return [Integer]
|
32
|
+
def self.convert_from_base(digits_ary, source_base)
|
33
|
+
# The numeric base is the number of digits in the source base.
|
34
|
+
numeric_base = source_base.count
|
35
|
+
|
36
|
+
digits_ary.reverse.each.with_index.reduce(0) do |value, (digit, position)|
|
37
|
+
# The value of `digit` in the source base is simply the index of `digit`
|
38
|
+
# in the `@source_base` array.
|
39
|
+
digit_value_in_base10 = source_base.find_index(digit)
|
40
|
+
value + (digit_value_in_base10 * (numeric_base**position))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Bases
|
4
|
+
# Base 62, the alphanumeric characters.
|
5
|
+
B62 = (
|
6
|
+
('A'..'Z').to_a +
|
7
|
+
('a'..'z').to_a +
|
8
|
+
(0..9).to_a
|
9
|
+
).map(&:to_s)
|
10
|
+
|
11
|
+
# Base 64.
|
12
|
+
# @see http://en.wikipedia.org/wiki/Base64.
|
13
|
+
B64 = B62 + %w(+ /)
|
14
|
+
|
15
|
+
|
16
|
+
# This error is thrown when an invalid value is passed to `Number`'s
|
17
|
+
# constructor.
|
18
|
+
InvalidValueError = Class.new(StandardError)
|
19
|
+
|
20
|
+
# This error is thrown when you try to convert a number without a specified
|
21
|
+
# base to another base.
|
22
|
+
NoBaseSpecifiedError = Class.new(StandardError)
|
23
|
+
|
24
|
+
# This error is thrown when there are digits in a value which aren't in the
|
25
|
+
# specified source base.
|
26
|
+
WrongDigitsError = Class.new(StandardError)
|
27
|
+
|
28
|
+
# This error is thrown when there are duplicates digits in a base.
|
29
|
+
# @example
|
30
|
+
# bad_base_3 = [0, 1, 0]
|
31
|
+
DuplicateDigitsError = Class.new(StandardError)
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Some miscellaneous helper functions.
|
4
|
+
module Bases::Helpers
|
5
|
+
# Return `true` if there are duplicate elements in `ary`.
|
6
|
+
# @param [Array] ary
|
7
|
+
# @return [bool]
|
8
|
+
def self.are_there_duplicates?(ary)
|
9
|
+
ary.uniq.size != ary.size
|
10
|
+
end
|
11
|
+
|
12
|
+
# Return an array version of `base`. An *array version* of `base` means an
|
13
|
+
# array of **strings**. If `base` is already an array, a copy of that array
|
14
|
+
# but with all elements converted to strings is returned. If `base` is an
|
15
|
+
# integer (in base 10 :D) a range-like array going from 0 to `base` is
|
16
|
+
# returned.
|
17
|
+
# @param [Integer|Array] base
|
18
|
+
# @return [Array<String>]
|
19
|
+
# @raise [DuplicateDigitsError] if there are duplicate digits in the base (if
|
20
|
+
# it was passed as an array).
|
21
|
+
def self.base_to_array(base)
|
22
|
+
base = (base.is_a?(Array) ? base : (0...base)).map(&:to_s)
|
23
|
+
|
24
|
+
if are_there_duplicates?(base)
|
25
|
+
fail Bases::DuplicateDigitsError,
|
26
|
+
'There are duplicate digits in the base'
|
27
|
+
else
|
28
|
+
base
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Check whether `digits` contains some digits that are not in `base`.
|
33
|
+
# @param [Array<String>] digits An array of digits
|
34
|
+
# @param [Array] base The base expressed as an array as everywhere else
|
35
|
+
# @return [boolean]
|
36
|
+
def self.only_valid_digits?(digits, base)
|
37
|
+
digits.all? { |digit| base.include?(digit) }
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Some monkeypatches to the `Array` class.
|
4
|
+
class Array
|
5
|
+
# Return a `Bases::Number` instance with the current array as the
|
6
|
+
# value and the source base set to `base`.
|
7
|
+
# @param (see Bases::Number#in_base)
|
8
|
+
# @return [Number]
|
9
|
+
# @see Bases::Number#in_base
|
10
|
+
def in_base(base)
|
11
|
+
Bases.val(self).in_base(base)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return a `Bases::Number` instance with the current array as the
|
15
|
+
# value and the source base set to the binary base.
|
16
|
+
# @return [Number]
|
17
|
+
# @see Bases::Number#in_binary
|
18
|
+
def in_binary
|
19
|
+
Bases.val(self).in_binary
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return a `Bases::Number` instance with the current array as the
|
23
|
+
# value and the source base set to the hexadecimale base.
|
24
|
+
# @return [Number]
|
25
|
+
# @see Bases::Number#in_hex
|
26
|
+
def in_hex
|
27
|
+
Bases.val(self).in_hex
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Some monkeypatches to the `Integer` class.
|
4
|
+
class Integer
|
5
|
+
# Convert this number to a given `base`.
|
6
|
+
# @param (see Bases::Number#to_base)
|
7
|
+
# @return [String]
|
8
|
+
# @see Bases::Number#to_base
|
9
|
+
def to_base(base, opts = {})
|
10
|
+
Bases.val(self).to_base(base, opts)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Convert this number in binary form.
|
14
|
+
# @return [String]
|
15
|
+
# @see Bases::Number#to_binary
|
16
|
+
def to_binary
|
17
|
+
to_base(2)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Convert this number in hexadecimal form.
|
21
|
+
# @return [String]
|
22
|
+
# @see Bases::Number#to_hex
|
23
|
+
def to_hex
|
24
|
+
to_base(16)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Some monkeypatches to the `String` class.
|
4
|
+
class String
|
5
|
+
# Return a `Bases::Number` instance with the current string as the
|
6
|
+
# value and the source base set to `base`.
|
7
|
+
# @param (see Bases::Number#in_base)
|
8
|
+
# @return [Number]
|
9
|
+
# @see Bases::Number#in_base
|
10
|
+
def in_base(base)
|
11
|
+
Bases.val(self).in_base(base)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Return a `Bases::Number` instance with the current string as the
|
15
|
+
# value and the source base set to the binary base.
|
16
|
+
# @return [Number]
|
17
|
+
# @see Bases::Number#in_binary
|
18
|
+
def in_binary
|
19
|
+
Bases.val(self).in_binary
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return a `Bases::Number` instance with the current string as the
|
23
|
+
# value and the source base set to the hexadecimale base.
|
24
|
+
# @return [Number]
|
25
|
+
# @see Bases::Number#in_hex
|
26
|
+
def in_hex
|
27
|
+
Bases.val(self).in_hex
|
28
|
+
end
|
29
|
+
end
|
data/lib/bases/number.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# The main class provided by Bases. It represents a base-agnostic
|
4
|
+
# number which can be forced to be interpreted in any base and then converted in
|
5
|
+
# any base.
|
6
|
+
class Bases::Number
|
7
|
+
# Create a new instance from a given `value`. If that value is an intance of a
|
8
|
+
# subclass of `Integer` (a `Bignum` or a `Fixnum`), it will be assumed to be
|
9
|
+
# in base 10 and any call to `in_base` on the new instance will result in an
|
10
|
+
# exception.
|
11
|
+
#
|
12
|
+
# If it is a `String`, no base will be assumed; if there are spaces
|
13
|
+
# in the string, they're used to separate the *multicharacter* digits,
|
14
|
+
# otherwise each character is assumed to be a digit.
|
15
|
+
#
|
16
|
+
# It `value` is an `Array`, each element in the array is assumed to be a
|
17
|
+
# digit. The array is read like a normal number, where digits on the left are
|
18
|
+
# more significative than digits on the right.
|
19
|
+
#
|
20
|
+
# @param [Integer|String|Array] value
|
21
|
+
# @raise [InvalidValueError] if `value` isn't a `String`, an `Integer` or an
|
22
|
+
# `Array`
|
23
|
+
def initialize(value)
|
24
|
+
case value
|
25
|
+
when Integer
|
26
|
+
@source_base = helpers.base_to_array(10)
|
27
|
+
@value = value
|
28
|
+
when String
|
29
|
+
@digits = (value =~ /\s/) ? value.split : value.split('')
|
30
|
+
when Array
|
31
|
+
@digits = value.map(&:to_s)
|
32
|
+
else
|
33
|
+
fail Bases::InvalidValueError, "#{value} isn't a valid value"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the source base of the current number. The `base` can be either a number
|
38
|
+
# (like 2 for binary or 16 for hexadecimal) or an array. In the latter case,
|
39
|
+
# the array is considered the whole base. For example, the binary base would
|
40
|
+
# be represented as `[0, 1]`; another binary base could be `[:a, :b]` and so
|
41
|
+
# on.
|
42
|
+
#
|
43
|
+
# **Note** that when the base is an integer up to 36, the native Ruby
|
44
|
+
# `Integer#to_i(base)` method is used for efficiency and clarity. However,
|
45
|
+
# this means that digits in a base 36 are numbers *and* letters, while digits
|
46
|
+
# in base 37 and more are only numbers (interpreted as multichar digits).
|
47
|
+
#
|
48
|
+
# `self` is returned in order to allow nice-looking chaining.
|
49
|
+
#
|
50
|
+
# @param [Integer|Array] base
|
51
|
+
# @return self
|
52
|
+
# @raise [WrongDigitsError] if there are digits in the previously specified
|
53
|
+
# value that are not present in `base`.
|
54
|
+
def in_base(base)
|
55
|
+
@source_base = helpers.base_to_array(base)
|
56
|
+
|
57
|
+
if native_ruby_base?(base)
|
58
|
+
@value = @digits.join('').to_i(base)
|
59
|
+
return self
|
60
|
+
end
|
61
|
+
|
62
|
+
# Make sure `@digits` contains only valid digits.
|
63
|
+
unless helpers.only_valid_digits?(@digits, @source_base)
|
64
|
+
fail Bases::WrongDigitsError,
|
65
|
+
"Some digits weren't in base #{base}"
|
66
|
+
end
|
67
|
+
|
68
|
+
@value = algorithms.convert_from_base(@digits, @source_base)
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
# Return a string representation of the current number in a `new_base`.
|
73
|
+
# A **string** representation is always returned, even if `new_base` is 10. If
|
74
|
+
# you're using base 10 and want an integer, just call `to_i` on the resulting
|
75
|
+
# string.
|
76
|
+
#
|
77
|
+
# @example With the default separator
|
78
|
+
# Number.new(3).to_base(2) #=> '11'
|
79
|
+
# @example With a different separator
|
80
|
+
# Number.new(3).to_base(2, separator: ' ~ ') #=> '1 ~ 1'
|
81
|
+
#
|
82
|
+
# @param [Integer|Array] new_base The same as in `in_base`
|
83
|
+
# @param [Hash] opts A small hash of options
|
84
|
+
# @option opts [bool] :array If true, return the result as an array of digits;
|
85
|
+
# otherwise, return a string. This defaults to `false`.
|
86
|
+
# @return [Array<String>|String]
|
87
|
+
# @raise [NoBaseSpecifiedError] if no source base was specified (either by
|
88
|
+
# passing an integer to the constructor or by using the `in_base` method)
|
89
|
+
def to_base(new_base, opts = {})
|
90
|
+
opts[:array] = false if opts[:array].nil?
|
91
|
+
|
92
|
+
unless defined?(@source_base)
|
93
|
+
fail Bases::NoBaseSpecifiedError, 'No base was specified'
|
94
|
+
end
|
95
|
+
|
96
|
+
# Let's apply the base conversion algorithm, which returns an array of
|
97
|
+
# digits.
|
98
|
+
res = if native_ruby_base?(new_base)
|
99
|
+
@value.to_s(new_base).split('')
|
100
|
+
else
|
101
|
+
algorithms.convert_to_base(@value, helpers.base_to_array(new_base))
|
102
|
+
end
|
103
|
+
|
104
|
+
opts[:array] ? res : res.join('')
|
105
|
+
end
|
106
|
+
|
107
|
+
# This function assumes you want the output in base 10 and returns an integer
|
108
|
+
# instead of a string (which would be returned after a call to `to_base(10)`).
|
109
|
+
# This was introduced so that `to_i` is adapted to the standard of returning
|
110
|
+
# an integer (in base 10, as Ruby represents integers).
|
111
|
+
# @return [Integer]
|
112
|
+
def to_i
|
113
|
+
to_base(10).to_i
|
114
|
+
end
|
115
|
+
|
116
|
+
# Specify that the current number is in hexadecimal representation.
|
117
|
+
# @note If you want to parse an hexadecimal number ignoring case-sensitivity,
|
118
|
+
# you **can't** use `in_base(Bases::HEX)` since that assumes
|
119
|
+
# upper case digits. You **have** to use `in_hex`, which internally just
|
120
|
+
# calls `String#hex`.
|
121
|
+
# @return [self]
|
122
|
+
def in_hex
|
123
|
+
@source_base = helpers.base_to_array(16)
|
124
|
+
@value = @digits.join('').hex
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
# Specify that the current number is in binary representation. This is just a
|
129
|
+
# shortcut for `in_base(2)` or `in_base([0, 1])`.
|
130
|
+
# @return [self]
|
131
|
+
def in_binary
|
132
|
+
in_base(2)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Just an alias to `to_base(2)`.
|
136
|
+
# @see Number#to_base
|
137
|
+
# @return [String]
|
138
|
+
def to_binary
|
139
|
+
to_base(2)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Just an alias to `to_base(Bases::HEX)`.
|
143
|
+
# @see Numer#to_base
|
144
|
+
# @return [String]
|
145
|
+
def to_hex
|
146
|
+
to_base(16)
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def native_ruby_base?(base)
|
152
|
+
base.is_a?(Fixnum) && base.between?(2, 36)
|
153
|
+
end
|
154
|
+
|
155
|
+
# A facility method for accessing the `Algorithms` module.
|
156
|
+
def algorithms
|
157
|
+
Bases::Algorithms
|
158
|
+
end
|
159
|
+
|
160
|
+
# A facility method for accessing the `Helpers` module.
|
161
|
+
def helpers
|
162
|
+
Bases::Helpers
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative 'test_helper'
|
4
|
+
|
5
|
+
class HelpersTest < Minitest::Test
|
6
|
+
def test_are_there_duplicates?
|
7
|
+
assert helpers.are_there_duplicates?([0, 1, 0])
|
8
|
+
assert helpers.are_there_duplicates?([2, 2, 2])
|
9
|
+
assert helpers.are_there_duplicates?([nil, nil])
|
10
|
+
refute helpers.are_there_duplicates?([])
|
11
|
+
refute helpers.are_there_duplicates?([1, '1'])
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_base_to_array
|
15
|
+
assert_equal %w(0 1), helpers.base_to_array(2)
|
16
|
+
assert_equal %w(0 1), helpers.base_to_array([0, 1])
|
17
|
+
assert_equal (0...10).map(&:to_s), helpers.base_to_array(10)
|
18
|
+
assert_equal %w(foo bar), helpers.base_to_array(%w(foo bar))
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_only_valid_digits
|
22
|
+
assert helpers.only_valid_digits?(%w(f o o), %(f o))
|
23
|
+
assert helpers.only_valid_digits?(%w(f o o), %(foo bar))
|
24
|
+
assert helpers.only_valid_digits?(%w(foo bar foo), %(foo bar))
|
25
|
+
refute helpers.only_valid_digits?(%w(foo bar baz), %(foo bar))
|
26
|
+
refute helpers.only_valid_digits?(%w(012), %(0 1))
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def helpers
|
32
|
+
Bases::Helpers
|
33
|
+
end
|
34
|
+
end
|
data/test/misc_test.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative 'test_helper'
|
4
|
+
|
5
|
+
class MiscTest < Minitest::Test
|
6
|
+
def test_some_basic_bases_are_defined
|
7
|
+
assert_const_defined :B62
|
8
|
+
assert_const_defined :B64
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_val
|
12
|
+
assert_respond_to mod, :val
|
13
|
+
assert_instance_of mod::Number, mod.val(33)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_brackets
|
17
|
+
assert_respond_to mod, :[]
|
18
|
+
assert_instance_of mod::Number, mod[0xba]
|
19
|
+
assert_equal 044, mod['44'].in_base(8).to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def assert_const_defined(const)
|
25
|
+
assert mod.const_defined?(const),
|
26
|
+
"#{const} is not defined in module #mod"
|
27
|
+
end
|
28
|
+
|
29
|
+
def mod
|
30
|
+
Bases
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative 'test_helper'
|
4
|
+
require_relative '../lib/bases/monkeypatches'
|
5
|
+
|
6
|
+
module MonkeypatchesTests
|
7
|
+
class IntegerTest < Minitest::Test
|
8
|
+
def test_to_base
|
9
|
+
assert_equal '10', 10.to_base(10)
|
10
|
+
assert_equal '10', 0b1010.to_base(10)
|
11
|
+
assert_equal 'A', 0xa.to_base(16).upcase
|
12
|
+
|
13
|
+
assert_equal %w(1 0), 2.to_base(2, array: true)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_common_methods
|
17
|
+
assert_equal '1010', 10.to_binary
|
18
|
+
assert_equal 'A', 10.to_hex.upcase
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class StringTest < Minitest::Test
|
23
|
+
def test_in_base
|
24
|
+
assert_equal '2', '10'.in_base(2).to_hex
|
25
|
+
assert_equal '1010', 'A'.in_base(16).to_base(2)
|
26
|
+
assert_equal '1010', 'baba'.in_base([:a, :b]).to_base(2)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_common_methods
|
30
|
+
assert_equal 2, '10'.in_binary.to_i
|
31
|
+
assert_equal 2, 'bar foo'.in_base(%w(foo bar)).to_i
|
32
|
+
assert_equal 10, 'a'.in_hex.to_i
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class ArrayTest < Minitest::Test
|
37
|
+
def test_in_base
|
38
|
+
assert_equal 11, [1, 0, 1, 1].in_base(2).to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_common_methods
|
42
|
+
assert_equal 2, [1, 0].in_binary.to_i
|
43
|
+
assert_equal 171, ['a', 'b'].in_hex.to_i
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/test/number_test.rb
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative 'test_helper'
|
4
|
+
require 'digest'
|
5
|
+
|
6
|
+
class NumberTest < Minitest::Test
|
7
|
+
BASE64 = Bases::B64
|
8
|
+
|
9
|
+
NUMBERS_FROM_BASE10 = [
|
10
|
+
{ base10: 0, base: 2, value: '0' },
|
11
|
+
{ base10: 1, base: 2, value: '1' },
|
12
|
+
{ base10: 2, base: 2, value: '10' },
|
13
|
+
{ base10: 4, base: 2, value: '100' },
|
14
|
+
{ base10: 9, base: 2, value: '1001' },
|
15
|
+
{ base10: 0, base: 16, value: '0' },
|
16
|
+
{ base10: 15, base: 16, value: 'f' },
|
17
|
+
{ base10: 16, base: 16, value: '10' },
|
18
|
+
{ base10: 3, base: 3, value: '10' },
|
19
|
+
{ base10: 0, base: %w(≈ y), value: '≈' },
|
20
|
+
{ base10: 8, base: %w(≈ +), value: '+≈≈≈' },
|
21
|
+
{ base10: 63, base: BASE64, value: '/' }
|
22
|
+
]
|
23
|
+
|
24
|
+
def test_from_base10_integer_to_any_base
|
25
|
+
NUMBERS_FROM_BASE10.each do |num_data|
|
26
|
+
result = n(num_data[:base10]).to_base(num_data[:base])
|
27
|
+
assert_equal num_data[:value], result
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_from_any_base_to_base10
|
32
|
+
NUMBERS_FROM_BASE10.each do |num_data|
|
33
|
+
result = n(num_data[:value]).in_base(num_data[:base]).to_i
|
34
|
+
assert_equal num_data[:base10], result
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_easy_to_see_numbers_and_identities
|
39
|
+
assert_equal 'fade', n(0xfade).to_base(16).downcase
|
40
|
+
assert_equal '71', n(071).to_base(8)
|
41
|
+
assert_equal '1010110', n(0b1010110).to_base(2)
|
42
|
+
|
43
|
+
assert_equal '10', n('10').in_base(2).to_base(2)
|
44
|
+
assert_equal 10, n(10).to_i
|
45
|
+
|
46
|
+
val = 'fwrfwasgefrfqf1r3f43131'
|
47
|
+
assert_equal val, n(val).in_base(BASE64).to_base(BASE64)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_facility_methods
|
51
|
+
assert_equal 10, n('a').in_hex.to_base(10).to_i
|
52
|
+
assert_equal 10, n('1010').in_binary.to_base(10).to_i
|
53
|
+
assert_equal '1010', n(10).to_binary
|
54
|
+
assert_equal 'A', n(10).to_hex.upcase
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_multichar_digits
|
58
|
+
assert_equal 2, n(%w(bar foo)).in_base(%w(foo bar)).to_i
|
59
|
+
assert_equal 1, n('hello world').in_base(%w(hello world)).to_i
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_duplicate_digits_are_checked
|
63
|
+
ex = Bases::DuplicateDigitsError
|
64
|
+
assert_raises(ex) { n(2).to_base([0, 1, 0]) }
|
65
|
+
assert_raises(ex) { n('foo bar').in_base(%w(foo foo)) }
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_initial_value_type_is_checked
|
69
|
+
ex = Bases::InvalidValueError
|
70
|
+
|
71
|
+
assert_raises(ex) { n({}) }
|
72
|
+
assert_raises(ex) { n(nil) }
|
73
|
+
assert_raises(ex) { n(0..10) }
|
74
|
+
assert_raises(ex) { n(Object.new) }
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_digits_are_checked_for_belonging_to_the_base
|
78
|
+
ex = Bases::WrongDigitsError
|
79
|
+
assert_raises(ex) { n('foo bar baz').in_base(%w(foo bar)) }
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_an_exception_is_thrown_if_no_base_is_specified
|
83
|
+
ex = Bases::NoBaseSpecifiedError
|
84
|
+
assert_raises(ex) { n('10').to_base(10) }
|
85
|
+
assert_raises(ex) { n('A').to_i }
|
86
|
+
assert_raises(ex) { n(%w(foo bar)).to_base(3) }
|
87
|
+
assert_raises(ex) { n([0, 2]).to_i }
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_leading_zeros_are_harmless
|
91
|
+
assert_equal 2, n('00000010').in_base(2).to_i
|
92
|
+
assert_equal 10, n('0a').in_hex.to_i
|
93
|
+
assert_equal 1, n(%w(foo bar)).in_base(%w(foo bar)).to_i
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_to_i
|
97
|
+
assert_equal 10, n('A').in_base(16).to_i
|
98
|
+
assert_equal 10, n('a').in_base(16).to_i
|
99
|
+
assert_equal 10, n('1010').in_base(2).to_i
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_edge_cases
|
103
|
+
assert_equal 0, n([]).in_base(2).to_i
|
104
|
+
assert_equal 0, n('').in_base(10).to_i
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_bignums_are_supported
|
108
|
+
value = n('//////////////').in_base(BASE64).to_i
|
109
|
+
assert_instance_of Bignum, value
|
110
|
+
|
111
|
+
# MD5 are hex numbers, very big ones too!
|
112
|
+
hex = Digest::MD5.hexdigest('foo bar')
|
113
|
+
|
114
|
+
# They convert easily to bignums...
|
115
|
+
assert_instance_of Bignum, n(hex).in_base(16).to_i
|
116
|
+
|
117
|
+
# ...and to base 3 numbers (check that the resulting number is composed of
|
118
|
+
# only the 0, 1 and 2 digits.
|
119
|
+
binary_digits = n(hex).in_base(16).to_base(3)
|
120
|
+
.split('').uniq.map(&:to_i).sort
|
121
|
+
assert_equal [0, 1, 2], binary_digits
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_to_base_outputting_an_array
|
125
|
+
assert_equal %w(b a b a), n(10).to_base([:a, :b], array: true)
|
126
|
+
assert_equal %w(1 0), n(2).to_base(2, array: true)
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_emojis_are_fun_and_💙
|
130
|
+
assert_equal '💙💚', n(2).to_base(['💚', '💙'])
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def n(val)
|
136
|
+
Bases::Number.new(val)
|
137
|
+
end
|
138
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# Coveralls coverage metrics.
|
4
|
+
require 'coveralls'
|
5
|
+
Coveralls.wear!
|
6
|
+
|
7
|
+
require 'minitest/autorun'
|
8
|
+
require 'minitest/pride'
|
9
|
+
require 'minitest/reporters'
|
10
|
+
|
11
|
+
require_relative '../lib/bases'
|
12
|
+
|
13
|
+
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bases
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrea Leopardi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: coveralls
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.7'
|
83
|
+
description: |2
|
84
|
+
This gem lets you convert integers from and to whatever base you like. You
|
85
|
+
can use array bases where you specify all the digits in the base,
|
86
|
+
multicharacter digits and other niceties. By default, this gem avoids
|
87
|
+
monkeypatching core Ruby classes, but it can be configured to monkeypatch
|
88
|
+
too.
|
89
|
+
email: an.leopardi@gmail.com
|
90
|
+
executables: []
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- ".coveralls.yml"
|
95
|
+
- ".gitignore"
|
96
|
+
- ".travis.yml"
|
97
|
+
- ".yardopts"
|
98
|
+
- Gemfile
|
99
|
+
- LICENSE.txt
|
100
|
+
- README.md
|
101
|
+
- Rakefile
|
102
|
+
- bases.gemspec
|
103
|
+
- lib/bases.rb
|
104
|
+
- lib/bases/algorithms.rb
|
105
|
+
- lib/bases/constants.rb
|
106
|
+
- lib/bases/helpers.rb
|
107
|
+
- lib/bases/monkeypatches.rb
|
108
|
+
- lib/bases/monkeypatches/array.rb
|
109
|
+
- lib/bases/monkeypatches/integer.rb
|
110
|
+
- lib/bases/monkeypatches/string.rb
|
111
|
+
- lib/bases/number.rb
|
112
|
+
- lib/bases/version.rb
|
113
|
+
- test/helpers_test.rb
|
114
|
+
- test/misc_test.rb
|
115
|
+
- test/monkeypatches_test.rb
|
116
|
+
- test/number_test.rb
|
117
|
+
- test/test_helper.rb
|
118
|
+
homepage: https://github.com/whatyouhide/bases
|
119
|
+
licenses:
|
120
|
+
- MIT
|
121
|
+
metadata: {}
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 2.2.2
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: Convert bases like a mofo.
|
142
|
+
test_files:
|
143
|
+
- test/helpers_test.rb
|
144
|
+
- test/misc_test.rb
|
145
|
+
- test/monkeypatches_test.rb
|
146
|
+
- test/number_test.rb
|
147
|
+
- test/test_helper.rb
|
148
|
+
has_rdoc:
|