general_units 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d17a99db7ba421efff46a40e27aec25b67f0e44c
4
- data.tar.gz: ea9bab404d037a00f20aeecb31dd3c1f1efbc783
3
+ metadata.gz: ee405e53d489845a7239d7301ff0d582caac6565
4
+ data.tar.gz: 38c046bb71f0908432f04d0be231c3c2214793a4
5
5
  SHA512:
6
- metadata.gz: 27da9ec610f978d90dce1ad760fd747e4b82f22fdf2a6043e8892bcb47353293734e8d0030a8030780d9c450120df3c2cf3e8b5d94f4e1c06bc9b70e0e64cd5f
7
- data.tar.gz: 98ee8f29fa85e44dcd98e834943472f24c64cb4cb48778d93a11c5fc91f0d6e7b4d6064ee9e31e724b5de02ab9885240f72e1fb4f68ba9dc9c23771a13e4d763
6
+ metadata.gz: 36399caf5fef89a3d11771717d96d91031e986b5fc729f0443b34635fd17dd358990cb9d5bf7877ec38e3fad50976c8c934426c0634a34c586397e34909c58f7
7
+ data.tar.gz: bee9e5c75aa9f697e56f488d64a1173c58a9f2dff345ee0a8c1f2e7fb9cc537fac1df4fafa30ca054ba8239525380bfb5370745aaa7b3cee0754d5ad7774afc8
data/.gitignore CHANGED
@@ -1,17 +1,5 @@
1
+ .DS_Store
1
2
  *.gem
2
- *.rbc
3
3
  .bundle
4
- .config
5
- .yardoc
6
4
  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
5
+ pkg/*
@@ -0,0 +1,163 @@
1
+ require 'general_units/units/length'
2
+
3
+ module GeneralUnits
4
+
5
+ class Box
6
+
7
+ VALUES = %w{length width height}
8
+
9
+ attr_reader *VALUES, :unit
10
+
11
+ def initialize(length = 0, width = 0, height = 0, unit)
12
+ VALUES.each {|v| instance_variable_set(:"@#{v}", validate_value(eval(v), unit))}
13
+ @unit = @height.unit
14
+ end
15
+
16
+ def values
17
+ VALUES.map {|v| self.send(v)}
18
+ end
19
+
20
+ def amount
21
+ length * width * height
22
+ end
23
+
24
+ def convert_to(unit)
25
+ Box.new(*values.map {|v| v.convert_to(unit).amount}, unit)
26
+ end
27
+
28
+ def to_s(round = 2)
29
+ "#{values.map(&:to_f).map {|f| f.round(round)}.join("x")} #{unit.short}"
30
+ end
31
+
32
+ def accommodates?(*boxes)
33
+ boxes.map! {|box| validate_capacity(box)}
34
+ boxes.sum(&:amount) < amount && includes?(Box.new(boxes.map(&:length).max, boxes.map(&:width).max, boxes.map(&:height).max, unit))
35
+ end
36
+
37
+ def same_size?(other_object)
38
+ other_object = validate_capacity(other_object)
39
+ eval VALUES.permutation.to_a.map {|values_names| "(length == other_object.#{values_names[0]} && width == other_object.#{values_names[1]} && height == other_object.#{values_names[2]})"}.join("||")
40
+ end
41
+
42
+ def includes?(other_object)
43
+ other_object = validate_capacity(other_object)
44
+ eval VALUES.permutation.to_a.map {|values_names| "(length >= other_object.#{values_names[0]} && width >= other_object.#{values_names[1]} && height >= other_object.#{values_names[2]})"}.join("||")
45
+ end
46
+
47
+ ### ARITHMETICS START ###
48
+
49
+ def -@
50
+ Box.new(*values.map {|v| -v}, unit)
51
+ end
52
+
53
+ def ==(other_object)
54
+ other_object = validate_capacity(other_object)
55
+ length == other_object.length && width == other_object.width && height == other_object.height
56
+ end
57
+
58
+ def eql?(other_object)
59
+ self == other_object
60
+ end
61
+
62
+ def <=>(val)
63
+ other_object = validate_capacity_or_length(other_object)
64
+ amount <=> case other_object
65
+ when Length then other_object
66
+ when Box then other_object.amount
67
+ end
68
+ end
69
+
70
+ def >(other_object)
71
+ other_object = validate_capacity_or_length(other_object)
72
+ amount > case other_object
73
+ when Length then other_object
74
+ when Box then other_object.amount
75
+ end
76
+ end
77
+
78
+ def <(other_object)
79
+ other_object = validate_capacity_or_length(other_object)
80
+ amount < case other_object
81
+ when Length then other_object
82
+ when Box then other_object.amount
83
+ end
84
+ end
85
+
86
+ def >=(other_object)
87
+ other_object = validate_capacity_or_length(other_object)
88
+ amount >= case other_object
89
+ when Length then other_object
90
+ when Box then other_object.amount
91
+ end
92
+ end
93
+
94
+ def <=(other_object)
95
+ other_object = validate_capacity_or_length(other_object)
96
+ amount <= case other_object
97
+ when Length then other_object
98
+ when Box then other_object.amount
99
+ end
100
+ end
101
+
102
+ delegate :positive?, :negative?, :to => :amount
103
+
104
+ def +(other_object)
105
+ other_object = validate_capacity_or_length(other_object)
106
+ case other_object
107
+ when Length then Box.new(*values.map {|v| v + other_object/3}, unit)
108
+ when Box then Box.new(*VALUES.map {|v| eval(v) + other_object.send(v)}, unit)
109
+ end
110
+ end
111
+
112
+ def -(other_object)
113
+ other_object = validate_capacity_or_length(other_object)
114
+ case other_object
115
+ when Length then Box.new(*values.map {|v| v - other_object/3}, unit)
116
+ when Box then Box.new(*VALUES.map {|v| eval(v) - other_object.send(v)}, unit)
117
+ end
118
+ end
119
+
120
+ def *(other_object)
121
+ other_object = validate_capacity_or_length(other_object)
122
+ case other_object
123
+ when Length then Box.new(*values.map {|v| v * other_object}, unit)
124
+ when Box then Box.new(*VALUES.map {|v| eval(v) * other_object.send(v)}, unit)
125
+ end
126
+ end
127
+
128
+ def /(other_object)
129
+ other_object = validate_capacity_or_length(other_object)
130
+ case other_object
131
+ when Length then Box.new(*values.map {|v| v / other_object}, unit)
132
+ when Box then Box.new(*VALUES.map {|v| eval(v) / other_object.send(v)}, unit)
133
+ end
134
+ end
135
+
136
+ delegate :div, :divmod, :modulo, :%, :remainder, :abs, :zero?, :nonzero?, :coerce, :to => :amount
137
+
138
+ ### ARITHMETICS END ###
139
+
140
+ private
141
+
142
+ def validate_value(val, unit)
143
+ val.is_a?(Length) ? val.convert_to(unit) : Length.new(val, unit)
144
+ end
145
+
146
+ def validate_capacity(val)
147
+ case val
148
+ when Box then val.convert_to(unit)
149
+ else raise(TypeError, "Box required, #{val.class} passed.")
150
+ end
151
+ end
152
+
153
+ def validate_capacity_or_length(val)
154
+ case val
155
+ when Box, Length then val.convert_to(unit)
156
+ when Numeric then val.to_length(unit)
157
+ else raise(TypeError, "Box or Length or Numeric required, #{val.class} passed.")
158
+ end
159
+ end
160
+
161
+ end
162
+
163
+ end
@@ -0,0 +1,4 @@
1
+ module GeneralUnits #:nodoc:
2
+ class Engine < ::Rails::Engine #:nodoc:
3
+ end
4
+ end
@@ -0,0 +1,11 @@
1
+ module GeneralUnits
2
+
3
+ module ActionViewExtension
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module GeneralUnits
2
+
3
+ module ActiveRecordExtension
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ class Numeric
2
+
3
+ def to_weight(unit = :gram)
4
+ GeneralUnits::Weight.new(self, unit)
5
+ end
6
+
7
+ def to_length(unit = :millimeter)
8
+ GeneralUnits::Length.new(self, unit)
9
+ end
10
+
11
+ end
@@ -0,0 +1,17 @@
1
+ require 'rails'
2
+
3
+ module GeneralUnits
4
+ class Railtie < ::Rails::Railtie
5
+ config.before_initialize do
6
+ ActiveSupport.on_load :active_record do
7
+ require 'general_units/models/active_record_extension'
8
+ include ActiveRecordExtension
9
+ end
10
+ ActiveSupport.on_load :action_view do
11
+ require 'general_units/helpers/action_view_extension'
12
+ include ActionViewExtension
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,152 @@
1
+ module GeneralUnits
2
+
3
+ module Arithmetics
4
+ def self.extend_class(klass)
5
+ unit_name = klass.name.split("::").last.underscore
6
+ klass.class_eval <<-EOV
7
+ delegate :to_f, :to_d, :to_i, :to => :amount
8
+
9
+ def -@
10
+ #{klass.name}.new(-amount, unit)
11
+ end
12
+
13
+ def ==(other_object)
14
+ other_object = other_object.to_#{unit_name} unless other_object.is_a?(#{klass.name})
15
+ amount == other_object.convert_to(unit).amount
16
+ rescue NoMethodError
17
+ false
18
+ end
19
+
20
+ def eql?(other_object)
21
+ self == other_object
22
+ end
23
+
24
+ def <=>(val)
25
+ val = val.to_#{unit_name}
26
+ unless amount == 0 || val.amount == 0 || unit == val.unit
27
+ val = val.convert_to(unit)
28
+ end
29
+ amount <=> val.amount
30
+ rescue NoMethodError
31
+ raise ArgumentError, "Comparison of #{self.class} with \#{val.inspect} failed"
32
+ end
33
+
34
+ def >(other_object)
35
+ other_object = other_object.is_a?(#{klass.name}) ? other_object.convert_to(unit) : other_object.to_#{unit_name}
36
+ amount > other_object.amount
37
+ end
38
+
39
+ def <(other_object)
40
+ other_object = other_object.is_a?(#{klass.name}) ? other_object.convert_to(unit) : other_object.to_#{unit_name}
41
+ amount < other_object.amount
42
+ end
43
+
44
+ def >=(other_object)
45
+ other_object = other_object.is_a?(#{klass.name}) ? other_object.convert_to(unit) : other_object.to_#{unit_name}
46
+ amount >= other_object.amount
47
+ end
48
+
49
+ def <=(other_object)
50
+ other_object = other_object.is_a?(#{klass.name}) ? other_object.convert_to(unit) : other_object.to_#{unit_name}
51
+ amount <= other_object.amount
52
+ end
53
+
54
+ def positive?
55
+ amount > 0
56
+ end
57
+
58
+ def negative?
59
+ amount < 0
60
+ end
61
+
62
+ def +(other_object)
63
+ other_object = other_object.is_a?(#{klass.name}) ? other_object.convert_to(unit) : other_object.to_#{unit_name}
64
+ #{klass.name}.new(amount + other_object.amount, unit)
65
+ end
66
+
67
+ def -(other_object)
68
+ other_object = other_object.is_a?(#{klass.name}) ? other_object.convert_to(unit) : other_object.to_#{unit_name}
69
+ #{klass.name}.new(amount - other_object.amount, unit)
70
+ end
71
+
72
+ def *(value)
73
+ case value
74
+ when Numeric then #{klass.name}.new(amount * value, unit)
75
+ when #{klass.name} then #{klass.name}.new(amount * value.convert_to(unit).amount, unit)
76
+ else raise ArgumentError, "Can't multiply a #{klass.name} by a \#{value.class.name}'s value"
77
+ end
78
+ end
79
+
80
+ def /(value)
81
+ case value
82
+ when Numeric then #{klass.name}.new(amount / value, unit)
83
+ when #{klass.name} then #{klass.name}.new(amount / value.convert_to(unit).amount, unit)
84
+ else raise ArgumentError, "Can't divide a #{klass.name} by a \#{value.class.name}'s value"
85
+ end
86
+ end
87
+
88
+ def div(value)
89
+ amount.div(value)
90
+ end
91
+
92
+ def divmod(val)
93
+ if val.is_a?(#{klass.name})
94
+ divmod_object(val)
95
+ else
96
+ divmod_other(val)
97
+ end
98
+ end
99
+
100
+ def divmod_object(val)
101
+ amount = val.convert_to(unit).amount
102
+ quotient, remainder = amount.divmod(amount)
103
+ [quotient, #{klass.name}.new(remainder, unit)]
104
+ end
105
+ private :divmod_object
106
+
107
+ def divmod_other(val)
108
+ quotient, remainder = amount.divmod(val.to_#{unit_name}(unit).amount)
109
+ [#{klass.name}.new(quotient, unit), #{klass.name}.new(remainder, unit)]
110
+ end
111
+ private :divmod_other
112
+
113
+ def modulo(val)
114
+ divmod(val)[1]
115
+ end
116
+
117
+ def %(val)
118
+ modulo(val)
119
+ end
120
+
121
+ def remainder(val)
122
+ if val.is_a?(#{klass.name}) && unit != val.unit
123
+ val = val.convert_to(unit)
124
+ end
125
+
126
+ if (amount < 0 && val < 0) || (amount > 0 && val > 0)
127
+ self.modulo(val)
128
+ else
129
+ self.modulo(val) - (val.is_a?(#{klass.name}) ? val : #{klass.name}.new(val, unit))
130
+ end
131
+ end
132
+
133
+ def abs
134
+ #{klass.name}.new(amount.abs, unit)
135
+ end
136
+
137
+ def zero?
138
+ amount == 0
139
+ end
140
+
141
+ def nonzero?
142
+ amount != 0 ? self : nil
143
+ end
144
+
145
+ def coerce(other)
146
+ [self, other]
147
+ end
148
+ EOV
149
+ end
150
+ end
151
+
152
+ end
@@ -0,0 +1,73 @@
1
+ require 'general_units/units/arithmetics/methods'
2
+
3
+ module GeneralUnits
4
+ class Length
5
+ ::GeneralUnits::Arithmetics.extend_class(self)
6
+
7
+ class Unit
8
+ attr_reader :name, :short, :millimeters
9
+
10
+ def initialize(name, short, millimeters)
11
+ @name = name.to_s
12
+ @short = short.to_s
13
+ @millimeters = millimeters.to_d
14
+ end
15
+
16
+ def to_s
17
+ name
18
+ end
19
+
20
+ def inspect
21
+ "\"#{name}\""
22
+ end
23
+ end
24
+
25
+ UNITS = {:mile_nautical => Unit.new("Mile (nautical)", "mln.", 1852000.0),
26
+ :mile => Unit.new("Mile", "ml.", 1609344.0),
27
+ :yard => Unit.new("Yard", "yrd.", 914.4),
28
+ :foot => Unit.new("Foot", "ft.", 304.8),
29
+ :inch => Unit.new("Inch", "in.", 25.4),
30
+ :kilometer => Unit.new("Kilometer", "km.", 1000000.0),
31
+ :meter => Unit.new("Meter", "m.", 1000.0),
32
+ :centimeter => Unit.new("Centimeter", "cm.", 10.0),
33
+ :millimeter => Unit.new("Millimeter", "mm.", 1.0)}
34
+
35
+ attr_reader :amount, :unit
36
+ delegate :to_f, :to => :amount
37
+
38
+ def initialize(amount = 0, unit)
39
+ if unit = valid_unit?(unit)
40
+ @amount = amount.try(:to_d)||0.to_d
41
+ @unit = unit
42
+ end
43
+ end
44
+
45
+ def convert_to(unit)
46
+ if convert_unit = valid_unit?(unit)
47
+ convert_amount = amount * @unit.millimeters/convert_unit.millimeters
48
+ Length.new(convert_amount, unit)
49
+ end
50
+ end
51
+
52
+ def to_s(round = 2)
53
+ "#{to_f.round(round)} #{unit.short}"
54
+ end
55
+
56
+ def to_length
57
+ self
58
+ end
59
+
60
+ private
61
+
62
+ def valid_unit?(unit)
63
+ unit_object = case unit
64
+ when String then UNITS[unit.to_sym]
65
+ when Symbol then UNITS[unit]
66
+ when Unit then unit
67
+ else UNITS[unit.to_s.to_sym]
68
+ end
69
+ unit_object || raise(TypeError, "Unprocessable unit #{unit.inspect}")
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,72 @@
1
+ require 'general_units/units/arithmetics/methods'
2
+
3
+ module GeneralUnits
4
+ class Weight
5
+ ::GeneralUnits::Arithmetics.extend_class(self)
6
+
7
+ class Unit
8
+ attr_reader :name, :short, :grams
9
+
10
+ def initialize(name, short, grams)
11
+ @name = name.to_s
12
+ @short = short.to_s
13
+ @grams = grams.to_d
14
+ end
15
+
16
+ def to_s
17
+ name
18
+ end
19
+
20
+ def inspect
21
+ "\"#{name}\""
22
+ end
23
+ end
24
+
25
+ UNITS = {:short_ton_us => Unit.new("Short ton (US)", "Sht.", 907184.74),
26
+ :pound_us => Unit.new("Pound (US)", "Pnd.", 453.59237),
27
+ :ounce_us => Unit.new("Ounce (US)", "Ounce", 28.349523),
28
+ :stone => Unit.new("Stone", "Stn", 6350.2932),
29
+ :long_ton_uk => Unit.new("Long Ton (UK)", "Lngt.", 1016046.9),
30
+ :metric_ton => Unit.new("Metric Ton", "Ton", 1000000.0),
31
+ :kilogram => Unit.new("Kilogram", "Kg.", 1000.0),
32
+ :gram => Unit.new("Gram", "g.", 1.0)}
33
+
34
+ attr_reader :amount, :unit
35
+ delegate :to_f, :to => :amount
36
+
37
+ def initialize(amount = 0, unit)
38
+ if unit = valid_unit?(unit)
39
+ @amount = amount.try(:to_d)||0.to_d
40
+ @unit = unit
41
+ end
42
+ end
43
+
44
+ def convert_to(unit)
45
+ if convert_unit = valid_unit?(unit)
46
+ convert_amount = amount * @unit.grams/convert_unit.grams
47
+ Weight.new(convert_amount, unit)
48
+ end
49
+ end
50
+
51
+ def to_s(round = 2)
52
+ "#{to_f.round(round)} #{unit.short}"
53
+ end
54
+
55
+ def to_weight
56
+ self
57
+ end
58
+
59
+ private
60
+
61
+ def valid_unit?(unit)
62
+ unit_object = case unit
63
+ when String then UNITS[unit.to_sym]
64
+ when Symbol then UNITS[unit]
65
+ when Unit then unit
66
+ else UNITS[unit.to_s.to_sym]
67
+ end
68
+ unit_object || raise(TypeError, "Unprocessable unit #{unit.inspect}")
69
+ end
70
+
71
+ end
72
+ end
@@ -1,3 +1,3 @@
1
1
  module GeneralUnits
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/general_units.rb CHANGED
@@ -4,6 +4,7 @@ module GeneralUnits
4
4
  def self.load!
5
5
  load_units!
6
6
  load_numeric!
7
+ load_derivatives!
7
8
  require 'general_units/engine'
8
9
  require 'general_units/railtie'
9
10
  end
@@ -16,6 +17,10 @@ module GeneralUnits
16
17
  def self.load_numeric!
17
18
  require 'general_units/numeric'
18
19
  end
20
+
21
+ def self.load_derivatives!
22
+ require 'general_units/derivatives/box'
23
+ end
19
24
 
20
25
  end
21
26
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: general_units
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valery Kvon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-10 00:00:00.000000000 Z
11
+ date: 2014-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -38,6 +38,15 @@ files:
38
38
  - Rakefile
39
39
  - general_units.gemspec
40
40
  - lib/general_units.rb
41
+ - lib/general_units/derivatives/box.rb
42
+ - lib/general_units/engine.rb
43
+ - lib/general_units/helpers/action_view_extension.rb
44
+ - lib/general_units/models/active_record_extension.rb
45
+ - lib/general_units/numeric.rb
46
+ - lib/general_units/railtie.rb
47
+ - lib/general_units/units/arithmetics/methods.rb
48
+ - lib/general_units/units/length.rb
49
+ - lib/general_units/units/weight.rb
41
50
  - lib/general_units/version.rb
42
51
  homepage: http://vkvon.ru/projects/general_units
43
52
  licenses: