measurement 0.2.2 → 0.2.3
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.
- 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
|
|