bases 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/whatyouhide/bases.svg?branch=master)](https://travis-ci.org/whatyouhide/bases)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/bases.svg)](http://badge.fury.io/rb/bases)
|
5
|
+
[![Coverage Status](https://img.shields.io/coveralls/whatyouhide/bases.svg)](https://coveralls.io/r/whatyouhide/bases)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/whatyouhide/bases/badges/gpa.svg)](https://codeclimate.com/github/whatyouhide/bases)
|
7
|
+
[![Dependency Status](https://gemnasium.com/whatyouhide/bases.svg)](https://gemnasium.com/whatyouhide/bases)
|
8
|
+
[![Inline docs](http://inch-ci.org/github/whatyouhide/bases.svg?branch=master&style=flat)](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:
|