store_as_int 0.0.6
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/lib/store_as_int.rb +117 -0
- data/lib/store_as_int/base.rb +162 -0
- data/lib/store_as_int/engine.rb +5 -0
- data/lib/store_as_int/exchange_rate.rb +7 -0
- data/lib/store_as_int/money.rb +7 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e3034a4265c20d3df48f06df60764ecece7e27b82e6d8b164d4832a2eedde3a9
|
4
|
+
data.tar.gz: 96f656f4ac06ed8af32d80e746a53e83b50cbe6e097a4aff52d6f7f6d267a270
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4468dc2c227c41bf027480939ad156be1ee972e3a72edf5cff5bee5918abfcc9c9d812498251acb5f3cf903a8710b62dbd722d34ba890dc40711591a4eb86eae
|
7
|
+
data.tar.gz: '098a626684c9223e4c2c5840d5c201434393f032e82f546415450bac8fa0ddd2118506308e6a866ee57dbdf60d0262b516dbcf50e0da04c24b11fb256bed9142'
|
data/lib/store_as_int.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# = StoreAsInt
|
2
|
+
#
|
3
|
+
# Seamlessly Store Decimal Values as Integers!
|
4
|
+
module StoreAsInt
|
5
|
+
|
6
|
+
if defined?(Rails)
|
7
|
+
require 'store_as_int/engine'
|
8
|
+
else
|
9
|
+
require 'store_as_int/exchange_rate'
|
10
|
+
require 'store_as_int/money'
|
11
|
+
end
|
12
|
+
|
13
|
+
# Create a new ::ExchangRate
|
14
|
+
#
|
15
|
+
# === Args
|
16
|
+
# val:: value to use with the exchange rate
|
17
|
+
#
|
18
|
+
# === Examples
|
19
|
+
# er = StoreAsInt.exchange_rate(1.234567890)
|
20
|
+
# OR
|
21
|
+
# er = StoreAsInt.exchange_rate('1.234567890')
|
22
|
+
# OR
|
23
|
+
# er = StoreAsInt.exchange_rate(1234567890)
|
24
|
+
#
|
25
|
+
# er.to_s => '1.2345'
|
26
|
+
# er.to_s(true) => '%1.2345'
|
27
|
+
# er.inspect => '%1.2345'
|
28
|
+
# er.to_d => 1.234567890
|
29
|
+
# er.value => 1234567890
|
30
|
+
#
|
31
|
+
def self.exchange_rate(val)
|
32
|
+
ExchangeRate.new(val)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Create a new ::Money
|
36
|
+
#
|
37
|
+
# === Args
|
38
|
+
# val:: value to use with the money
|
39
|
+
#
|
40
|
+
# === Examples
|
41
|
+
# er = StoreAsInt.money(1001.23)
|
42
|
+
# OR
|
43
|
+
# er = StoreAsInt.money("1001.23")
|
44
|
+
# OR
|
45
|
+
# er = StoreAsInt.money(100123)
|
46
|
+
#
|
47
|
+
# er.to_s => '1001.23'
|
48
|
+
# er.to_s(true) => '$1,001.23'
|
49
|
+
# er.inspect => '$1,001.23'
|
50
|
+
# er.to_d => 1001.23
|
51
|
+
# er.value => 100123
|
52
|
+
#
|
53
|
+
def self.money(val)
|
54
|
+
Money.new(val)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Register a new StoreAsInt type
|
58
|
+
#
|
59
|
+
# === Args
|
60
|
+
# under_scored_class_name:: @string - method name to use when initializing
|
61
|
+
# base_value:: @integer - number to multiply and divide by when doing conversions
|
62
|
+
# number_of_decimals:: @integer - number of decimals to include in to_s method
|
63
|
+
# symbol_to_use:: @string - symbol to use in to_s method
|
64
|
+
# &block::
|
65
|
+
# @block - override to_s method with a block.
|
66
|
+
# called with arguments (self, w_sym)
|
67
|
+
# where w_sym is a boolean for whether to include symbol in the returned string
|
68
|
+
#
|
69
|
+
# === Examples
|
70
|
+
# StoreAsInt.register 'accurate_money', 10000, 2, '$'
|
71
|
+
#
|
72
|
+
# am = StoreAsInt::AccurateMoney.new(1.2345)
|
73
|
+
# am.to_s(true) => $1.23
|
74
|
+
# am.value => 12345
|
75
|
+
#
|
76
|
+
# ----------
|
77
|
+
#
|
78
|
+
# StoreAsInt.register 'custom_to_s', 100, 2, '$' do |passed, w_sym|
|
79
|
+
# "CUSTOM_STR #{passed.negative_sign}#{passed.sym}#{sprintf("%0.0#{passed.decimals}f", passed.to_d.abs)}"
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# cts = StoreAsInt.custom_to_s(-1.23)
|
83
|
+
# cts.to_s(true) => CUSTOM_STR -$1.23
|
84
|
+
# cts.to_s => CUSTOM_STR -$1.23
|
85
|
+
# cts.value => -123
|
86
|
+
#
|
87
|
+
def self.register(under_scored_class_name, base_value = 1, number_of_decimals = 0, symbol_to_use = '', &block)
|
88
|
+
const_name = under_scored_class_name.split('_').map(&:capitalize).join('')
|
89
|
+
|
90
|
+
begin
|
91
|
+
const_get(const_name)
|
92
|
+
|
93
|
+
puts "WARNING - #{const_name} Already Registered. Nothing has been done"
|
94
|
+
rescue NameError
|
95
|
+
puts " - Registering StoreAsInt::#{const_name}"
|
96
|
+
|
97
|
+
const_set const_name, Class.new(StoreAsInt::Base)
|
98
|
+
|
99
|
+
puts " - Registering local constants for StoreAsInt::#{const_name}"
|
100
|
+
|
101
|
+
const_get(const_name).const_set 'BASE', (base_value && base_value.to_i) || 1
|
102
|
+
const_get(const_name).const_set 'DECIMALS', number_of_decimals.to_i
|
103
|
+
const_get(const_name).const_set 'SYM', symbol_to_use.to_s
|
104
|
+
const_get(const_name).const_set 'STR_FORMAT', block || nil
|
105
|
+
|
106
|
+
puts " - Registering shortcut method: StoreAsInt.#{under_scored_class_name}(value)"
|
107
|
+
|
108
|
+
define_singleton_method under_scored_class_name.to_sym do |val|
|
109
|
+
const_get(const_name).new(val)
|
110
|
+
end
|
111
|
+
|
112
|
+
puts " - StoreAsInt::#{const_name} registered"
|
113
|
+
end
|
114
|
+
|
115
|
+
const_get(const_name)
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'bigdecimal/util'
|
3
|
+
|
4
|
+
module StoreAsInt
|
5
|
+
class Base
|
6
|
+
|
7
|
+
# == Constants ============================================================
|
8
|
+
BASE = 1
|
9
|
+
DECIMALS = nil
|
10
|
+
SYM = 1
|
11
|
+
STR_FORMAT = nil
|
12
|
+
|
13
|
+
# == Attributes ============================================================
|
14
|
+
attr_accessor :num
|
15
|
+
|
16
|
+
# == Extensions ===========================================================
|
17
|
+
include Comparable
|
18
|
+
|
19
|
+
# == Class Methods ========================================================
|
20
|
+
def self.===(other)
|
21
|
+
self === other || Integer === other
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.<=>(other)
|
25
|
+
self <=> other || Integer <=> other
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.base
|
29
|
+
self::BASE || 1
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.decimals
|
33
|
+
self::DECIMALS
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.sym
|
37
|
+
self::SYM || ''
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.str_format
|
41
|
+
self::STR_FORMAT
|
42
|
+
end
|
43
|
+
|
44
|
+
# == Instance Methods =====================================================
|
45
|
+
def initialize(new_val = nil)
|
46
|
+
return self.num = 0 unless new_val
|
47
|
+
|
48
|
+
if new_val.is_a?(self.class)
|
49
|
+
self.num = new_val.value
|
50
|
+
elsif new_val.is_a?(Integer)
|
51
|
+
self.num = new_val
|
52
|
+
else
|
53
|
+
self.num = (new_val.to_d * self.class.base).to_i
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def base
|
58
|
+
self.class.base
|
59
|
+
end
|
60
|
+
|
61
|
+
def decimals
|
62
|
+
@decimals ||= self.class.decimals
|
63
|
+
end
|
64
|
+
|
65
|
+
def base_float
|
66
|
+
base.to_f
|
67
|
+
end
|
68
|
+
|
69
|
+
def sym
|
70
|
+
@sym ||= self.class.sym
|
71
|
+
end
|
72
|
+
|
73
|
+
def sym=(new_sym)
|
74
|
+
@sym = new_sym
|
75
|
+
end
|
76
|
+
|
77
|
+
def convert(other_val)
|
78
|
+
self.class.new(other_val)
|
79
|
+
end
|
80
|
+
|
81
|
+
def <=>(compare)
|
82
|
+
value <=> convert(compare).value
|
83
|
+
end
|
84
|
+
|
85
|
+
def == (compare)
|
86
|
+
value == convert(compare).value
|
87
|
+
end
|
88
|
+
|
89
|
+
def kind_of?(klass)
|
90
|
+
self.num.kind_of?(klass)
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_i
|
94
|
+
self.num.to_i
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_f
|
98
|
+
to_i/base_float
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_d
|
102
|
+
to_i.to_d/base
|
103
|
+
end
|
104
|
+
|
105
|
+
def cents
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
def value
|
110
|
+
self.num || 0
|
111
|
+
end
|
112
|
+
|
113
|
+
def as_json(*args)
|
114
|
+
self.num.as_json(*args)
|
115
|
+
end
|
116
|
+
|
117
|
+
def inspect
|
118
|
+
to_s(true)
|
119
|
+
end
|
120
|
+
|
121
|
+
def negative_sign
|
122
|
+
value < 0 ? '-' : ''
|
123
|
+
end
|
124
|
+
|
125
|
+
def coerce(other)
|
126
|
+
[other, value]
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_s(w_sym = false)
|
130
|
+
begin
|
131
|
+
str_format.call(self, w_sym)
|
132
|
+
rescue
|
133
|
+
puts $!.message
|
134
|
+
puts $!.backtrace
|
135
|
+
""
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def present?
|
140
|
+
begin
|
141
|
+
value.present?
|
142
|
+
rescue NoMethodError
|
143
|
+
!value.nil? && !(value.to_s == "")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def method_missing(name, *args, &blk)
|
148
|
+
ret = value.send(name, *args, &blk)
|
149
|
+
ret.is_a?(Numeric) ? self.class.new(ret) : ret
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
def str_format
|
154
|
+
@str_format ||= self.class.str_format || ->(passed, w_sym) do
|
155
|
+
return nil unless w_sym || passed.present?
|
156
|
+
str = "#{passed.negative_sign}#{w_sym ? passed.sym : ''}#{passed.decimals ? sprintf("%0.0#{passed.decimals.to_i}f", passed.to_d.abs) : passed.to_i.to_s}".reverse.split('.')
|
157
|
+
str[-1] = str[-1].gsub(/(\d{3})(?=\d)/, w_sym ? '\\1,' : '\\1')
|
158
|
+
str.join('.').reverse
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: store_as_int
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sampson Crowley
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-06-09 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Seamlessly store different types of values (such as dollars) as integers
|
14
|
+
email: sampsonsprojects@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- lib/store_as_int.rb
|
20
|
+
- lib/store_as_int/base.rb
|
21
|
+
- lib/store_as_int/engine.rb
|
22
|
+
- lib/store_as_int/exchange_rate.rb
|
23
|
+
- lib/store_as_int/money.rb
|
24
|
+
homepage: http://rubygems.org/gems/store_as_int
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.7.6
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: Store values as integers for lossless calculations
|
48
|
+
test_files: []
|