general_units 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: