store_as_int 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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'
@@ -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
@@ -0,0 +1,5 @@
1
+ module StoreAsInt
2
+ class Engine < ::Rails::Engine
3
+ config.autoload_paths += Dir["#{config.root}/lib/**/"]
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require_relative './base'
2
+
3
+ class StoreAsInt::ExchangeRate < StoreAsInt::Base
4
+ BASE = 10000000000
5
+ DECIMALS = 4
6
+ SYM = '%'
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative './base'
2
+
3
+ class StoreAsInt::Money < StoreAsInt::Base
4
+ BASE = 100
5
+ DECIMALS = 2
6
+ SYM = '$'
7
+ 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: []