measurement 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/lib/measurement/length.rb +7 -7
- data/lib/measurement/unit.rb +12 -1
- data/lib/measurement/weight.rb +6 -5
- data/lib/measurement.rb +45 -29
- data/measurement.gemspec +2 -2
- data/spec/lib/measurement_spec.rb +37 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
data/lib/measurement/length.rb
CHANGED
@@ -21,14 +21,14 @@ require File.join(File.dirname(__FILE__), '..', 'measurement')
|
|
21
21
|
# puts Length.parse('180.34cm').in_feet_and_inches => 5' 11"
|
22
22
|
#
|
23
23
|
class Length < Measurement::Base
|
24
|
-
base :metre, :metres, :suffix => 'm'
|
25
|
-
unit 1000, :kilometre, :kilometres, :km, :suffix => 'km'
|
26
|
-
unit 0.01, :centimetre, :centimetres, :cm, :suffix => 'cm'
|
27
|
-
unit 0.001, :millimetre, :mm, :suffix => 'mm'
|
24
|
+
base :metre, :metres, :suffix => 'm', :group => :metric
|
25
|
+
unit 1000, :kilometre, :kilometres, :km, :suffix => 'km', :group => :metric
|
26
|
+
unit 0.01, :centimetre, :centimetres, :cm, :suffix => 'cm', :group => :metric
|
27
|
+
unit 0.001, :millimetre, :mm, :suffix => 'mm', :group => :metric
|
28
28
|
|
29
|
-
unit 0.0254, :inch, :inches, :suffix => '"'
|
30
|
-
unit 0.3048, :feet, :foot, :suffix => "'"
|
31
|
-
unit 1609.34, :mile, :miles, :suffix => ' miles'
|
29
|
+
unit 0.0254, :inch, :inches, :suffix => '"', :group => :imperial
|
30
|
+
unit 0.3048, :feet, :foot, :suffix => "'", :group => :imperial
|
31
|
+
unit 1609.34, :mile, :miles, :suffix => ' miles', :group => :imperial
|
32
32
|
unit 0.1016, :hand, :hands, :suffix => ' hands'
|
33
33
|
|
34
34
|
unit 299792458, :light_seconds, :suffix => ' light seconds'
|
data/lib/measurement/unit.rb
CHANGED
@@ -1,16 +1,27 @@
|
|
1
1
|
module Measurement
|
2
2
|
class Unit
|
3
|
-
|
3
|
+
include Comparable
|
4
|
+
|
5
|
+
attr_reader :names, :scale, :groups
|
4
6
|
|
5
7
|
def initialize(scale, *args)
|
6
8
|
@options = args.last.is_a?(Hash) ? args.pop : {}
|
7
9
|
@names = args
|
8
10
|
@scale = scale
|
11
|
+
@groups = [@options[:group]].flatten
|
12
|
+
end
|
13
|
+
|
14
|
+
def <=>(anOther)
|
15
|
+
scale <=> anOther.scale
|
9
16
|
end
|
10
17
|
|
11
18
|
def has_name?(name)
|
12
19
|
names.include?(name)
|
13
20
|
end
|
21
|
+
|
22
|
+
def in_group?(group)
|
23
|
+
groups.include?(group.to_sym)
|
24
|
+
end
|
14
25
|
|
15
26
|
def from(amount)
|
16
27
|
amount.to_f * @scale
|
data/lib/measurement/weight.rb
CHANGED
@@ -16,9 +16,10 @@ require File.join(File.dirname(__FILE__), '..', 'measurement')
|
|
16
16
|
# puts Length.parse('100kg').in_lbs_and_oz => 220lbs 7oz
|
17
17
|
#
|
18
18
|
class Weight < Measurement::Base
|
19
|
-
base :gram, :grams, :suffix => 'g'
|
20
|
-
unit 1000.0, :kilogram, :kilograms, :kg, :kgs, :suffix => 'kg'
|
21
|
-
|
22
|
-
unit
|
23
|
-
unit
|
19
|
+
base :gram, :grams, :suffix => 'g', :group => :metric
|
20
|
+
unit 1000.0, :kilogram, :kilograms, :kg, :kgs, :suffix => 'kg', :group => :metric
|
21
|
+
|
22
|
+
unit 453.59236, :pounds, :pound, :lbs, :suffix => 'lbs', :group => [:imperial, :us]
|
23
|
+
unit 28.3495231, :ounces, :ounce, :oz, :suffix => 'oz', :group => :us
|
24
|
+
unit 6350.29318, :stone, :st, :suffix => 'st', :group => :imperial
|
24
25
|
end
|
data/lib/measurement.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'measurement', 'unit')
|
2
|
+
require File.join(File.dirname(__FILE__), 'measurement', 'unit_group')
|
2
3
|
|
3
4
|
module Measurement
|
4
5
|
class NoUnitFoundException < Exception
|
@@ -62,21 +63,23 @@ module Measurement
|
|
62
63
|
end
|
63
64
|
|
64
65
|
def self.register_measurement
|
65
|
-
|
66
|
-
s
|
67
|
-
|
66
|
+
if name && name.length > 0
|
67
|
+
method_name = name.gsub(/\s/, '_').gsub(/.[A-Z]/) do |s|
|
68
|
+
s[0,1] + '_' + s[1,1].downcase
|
69
|
+
end.downcase
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
[Fixnum, Float].each do |klass|
|
72
|
+
klass.class_eval %Q{
|
73
|
+
def to_#{method_name}
|
74
|
+
#{name}.new(self)
|
75
|
+
end}
|
76
|
+
end
|
75
77
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
78
|
+
String.class_eval %Q{
|
79
|
+
def to_#{method_name}
|
80
|
+
#{name}.parse(self)
|
81
|
+
end}
|
82
|
+
end
|
80
83
|
end
|
81
84
|
|
82
85
|
def self.units # :nodoc:
|
@@ -101,6 +104,7 @@ module Measurement
|
|
101
104
|
#
|
102
105
|
# * <tt>prefix</tt> - A prefix to use when formatting the unit.
|
103
106
|
# * <tt>suffix</tt> - A suffix to use when formatting the unit.
|
107
|
+
# * <tt>group</tt> - A group that can be used when formatting to combine the unit formats.
|
104
108
|
#
|
105
109
|
def self.unit(unit, *args)
|
106
110
|
add_unit(Unit.new(unit, *args))
|
@@ -109,14 +113,29 @@ module Measurement
|
|
109
113
|
def self.add_unit(unit) # :nodoc:
|
110
114
|
units << unit
|
111
115
|
end
|
116
|
+
|
117
|
+
def self.fetch_group(scale) # :nodoc:
|
118
|
+
scale = scale.to_sym
|
119
|
+
@groups ||= {}
|
120
|
+
@groups[scale] ||= begin
|
121
|
+
group = units.inject([]) do |m,n|
|
122
|
+
m << n if n.in_group?(scale)
|
123
|
+
m
|
124
|
+
end
|
125
|
+
|
126
|
+
if group.any?
|
127
|
+
UnitGroup.new(group)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
112
131
|
|
113
|
-
def self.fetch_scale(scale = nil) # :nodoc:
|
132
|
+
def self.fetch_scale(scale = nil, raise_error = true) # :nodoc:
|
114
133
|
unit = (scale.nil? ? base : units.detect do |unit|
|
115
134
|
unit.has_name?(scale.to_sym)
|
116
|
-
end)
|
135
|
+
end) || fetch_group(scale)
|
117
136
|
|
118
137
|
unless unit
|
119
|
-
raise NoUnitFoundException.new(scale)
|
138
|
+
raise NoUnitFoundException.new(scale) if raise_error
|
120
139
|
else
|
121
140
|
unit
|
122
141
|
end
|
@@ -252,25 +271,22 @@ module Measurement
|
|
252
271
|
#
|
253
272
|
# Length.new(1.8034).in_feet_and_inches => 5' 11"
|
254
273
|
#
|
274
|
+
# The unit group can also be specified to get a similar effect:
|
275
|
+
#
|
276
|
+
# Length.new(1.8034).to_s(:metric) => '1m 80cm 3mm'
|
277
|
+
#
|
255
278
|
# A precision can be specified, otherwise the measurement
|
256
279
|
# is rounded to the nearest integer.
|
257
280
|
def to_s(unit = nil, precision = 0)
|
258
281
|
if unit.to_s =~ /_and_/
|
259
|
-
units = unit.to_s.split('_and_')
|
260
|
-
|
261
|
-
strs = []
|
262
|
-
|
263
|
-
while unit = units.shift
|
264
|
-
n_in = self.class.to(amount, unit.to_sym)
|
265
|
-
n_in = n_in.floor unless units.empty?
|
266
|
-
n_out = self.class.from(n_in, unit.to_sym)
|
267
|
-
amount -= self.class.from(n_in, unit.to_sym)
|
268
|
-
strs << self.class.format(n_out, unit.to_sym, 0)
|
282
|
+
units = unit.to_s.split('_and_').map do |unit|
|
283
|
+
self.class.fetch_scale(unit)
|
269
284
|
end
|
270
|
-
|
271
|
-
|
285
|
+
|
286
|
+
UnitGroup.new(units).format(@amount, precision)
|
272
287
|
else
|
273
|
-
self.class.
|
288
|
+
unit = self.class.fetch_scale(unit)
|
289
|
+
unit.format(@amount, precision)
|
274
290
|
end
|
275
291
|
end
|
276
292
|
alias_method :format, :to_s
|
data/measurement.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{measurement}
|
5
|
-
s.version = "0.2.
|
5
|
+
s.version = "0.2.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Jeremy Wells"]
|
9
|
-
s.date = %q{2010-
|
9
|
+
s.date = %q{2010-03-01}
|
10
10
|
s.description = %q{A library for holding, converting and formatting measurements}
|
11
11
|
s.email = %q{jemmyw@gmail.com}
|
12
12
|
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.rdoc", "lib/measurement.rb", "lib/measurement/length.rb", "lib/measurement/unit.rb", "lib/measurement/weight.rb"]
|
@@ -105,4 +105,41 @@ describe Measurement::Base do
|
|
105
105
|
length.in_cm_and_mm.should == length.to_s(:cm_and_mm)
|
106
106
|
end
|
107
107
|
end
|
108
|
+
|
109
|
+
describe '#to_s' do
|
110
|
+
before do
|
111
|
+
@klass = Class.new(Measurement::Base)
|
112
|
+
@klass.base :grams, :group => :metric, :suffix => 'g'
|
113
|
+
@klass.unit 1000, :kilograms, :group => :metric, :suffix => 'kg'
|
114
|
+
@instance = @klass.new(1500)
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should return the base unit format if no unit is specified' do
|
118
|
+
@instance.to_s.should == '1500g'
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should return the unit format if a unit is specified' do
|
122
|
+
@instance.to_s(:kilograms).should == '2kg'
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should return the unit format with precision if specified' do
|
126
|
+
@instance.to_s(:kilograms, 1).should == '1.5kg'
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should return the combined unit formats if separated by and' do
|
130
|
+
@instance.to_s(:kilograms_and_grams).should == '1kg 500g'
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'should return the combined unit formats if a group is specified' do
|
134
|
+
@instance.to_s(:metric).should == '1kg 500g'
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should not return any lower bound measurments if they are 0' do
|
138
|
+
@klass.new(10000).to_s(:metric).should == '10kg'
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should not return any upper bound measurements if they are 0' do
|
142
|
+
@klass.new(10).to_s(:metric).should == '10g'
|
143
|
+
end
|
144
|
+
end
|
108
145
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: measurement
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Wells
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-01 00:00:00 +13:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|