measurement 0.2 → 0.2.1
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.rb +55 -22
- data/measurement.gemspec +2 -2
- data/spec/lib/measurement_spec.rb +40 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
data/lib/measurement.rb
CHANGED
@@ -22,6 +22,8 @@ module Measurement
|
|
22
22
|
# Length.new(10).to_s(:qt, 3) => 0.005qt
|
23
23
|
#
|
24
24
|
class Base
|
25
|
+
include Comparable
|
26
|
+
|
25
27
|
# Define the base measurement unit. This method accepts
|
26
28
|
# a list of names for the base measurement, followed
|
27
29
|
# by the standard unit options. See #unit
|
@@ -39,14 +41,33 @@ module Measurement
|
|
39
41
|
# base unit.
|
40
42
|
#
|
41
43
|
def self.base(*args)
|
42
|
-
if args.any?
|
44
|
+
if args.any? || !@base
|
43
45
|
@base = Unit.new(1.0, *args)
|
44
46
|
add_unit(@base)
|
47
|
+
register_measurement
|
45
48
|
else
|
46
49
|
@base
|
47
50
|
end
|
48
51
|
end
|
49
52
|
|
53
|
+
def self.register_measurement
|
54
|
+
method_name = name.gsub(/\s/, '_').gsub(/.[A-Z]/) do |s|
|
55
|
+
s[0,1] + '_' + s[1,1].downcase
|
56
|
+
end.downcase
|
57
|
+
|
58
|
+
[Fixnum, Float].each do |klass|
|
59
|
+
klass.class_eval %Q{
|
60
|
+
def to_#{method_name}
|
61
|
+
#{name}.new(self)
|
62
|
+
end}
|
63
|
+
end
|
64
|
+
|
65
|
+
String.class_eval %Q{
|
66
|
+
def to_#{method_name}
|
67
|
+
#{name}.parse(self)
|
68
|
+
end}
|
69
|
+
end
|
70
|
+
|
50
71
|
def self.units # :nodoc:
|
51
72
|
@units ||= []
|
52
73
|
end
|
@@ -70,8 +91,8 @@ module Measurement
|
|
70
91
|
# * <tt>prefix</tt> - A prefix to use when formatting the unit.
|
71
92
|
# * <tt>suffix</tt> - A suffix to use when formatting the unit.
|
72
93
|
#
|
73
|
-
def self.unit(
|
74
|
-
add_unit(Unit.new(
|
94
|
+
def self.unit(unit, *args)
|
95
|
+
add_unit(Unit.new(unit, *args))
|
75
96
|
end
|
76
97
|
|
77
98
|
def self.add_unit(unit) # :nodoc:
|
@@ -91,16 +112,16 @@ module Measurement
|
|
91
112
|
end
|
92
113
|
end
|
93
114
|
|
94
|
-
def self.from(amount,
|
95
|
-
fetch_scale(
|
115
|
+
def self.from(amount, unit) # :nodoc:
|
116
|
+
fetch_scale(unit).from(amount)
|
96
117
|
end
|
97
118
|
|
98
|
-
def self.to(amount,
|
99
|
-
fetch_scale(
|
119
|
+
def self.to(amount, unit = nil) # :nodoc:
|
120
|
+
fetch_scale(unit).to(amount)
|
100
121
|
end
|
101
122
|
|
102
|
-
def self.format(amount,
|
103
|
-
fetch_scale(
|
123
|
+
def self.format(amount, unit = nil, precision = 2) #:nodoc:
|
124
|
+
fetch_scale(unit).format(amount, precision)
|
104
125
|
end
|
105
126
|
|
106
127
|
# Parse a string containing this measurement. The string
|
@@ -114,7 +135,7 @@ module Measurement
|
|
114
135
|
#
|
115
136
|
# If a valid unit cannot be found an error is raised:
|
116
137
|
#
|
117
|
-
# Weight.parse("180cm") => Measurement::
|
138
|
+
# Weight.parse("180cm") => Measurement::NoUnitException
|
118
139
|
#
|
119
140
|
def self.parse(string)
|
120
141
|
string = string.dup
|
@@ -122,15 +143,15 @@ module Measurement
|
|
122
143
|
|
123
144
|
while string =~ /(\d+(\.\d+)?)([^\d]*)/
|
124
145
|
amount = $1.to_f
|
125
|
-
|
146
|
+
unit = $3 && $3.strip
|
126
147
|
|
127
|
-
if
|
128
|
-
|
148
|
+
if unit && unit.length > 0
|
149
|
+
unit = find_scale(unit)
|
129
150
|
|
130
|
-
if
|
131
|
-
raise NoUnitFoundException.new(
|
151
|
+
if unit.nil?
|
152
|
+
raise NoUnitFoundException.new(unit)
|
132
153
|
else
|
133
|
-
base_amount +=
|
154
|
+
base_amount += unit.from(amount)
|
134
155
|
end
|
135
156
|
else
|
136
157
|
base_amount += amount
|
@@ -142,8 +163,8 @@ module Measurement
|
|
142
163
|
self.new(base_amount)
|
143
164
|
end
|
144
165
|
|
145
|
-
def initialize(amount = 0,
|
146
|
-
@amount = self.class.from(amount,
|
166
|
+
def initialize(amount = 0, unit = nil)
|
167
|
+
@amount = self.class.from(amount, unit)
|
147
168
|
end
|
148
169
|
|
149
170
|
# The base unit as an integer
|
@@ -155,6 +176,18 @@ module Measurement
|
|
155
176
|
def to_f
|
156
177
|
@amount.to_f
|
157
178
|
end
|
179
|
+
|
180
|
+
def <=>(anOther)
|
181
|
+
to_f <=> anOther.to_f
|
182
|
+
end
|
183
|
+
|
184
|
+
%w(+ - / *).each do |operator|
|
185
|
+
class_eval %Q{
|
186
|
+
def #{operator}(anOther)
|
187
|
+
self.class.new(self.to_f #{operator} anOther.to_f)
|
188
|
+
end
|
189
|
+
}
|
190
|
+
end
|
158
191
|
|
159
192
|
# This measurement converted to the specified unit.
|
160
193
|
#
|
@@ -173,11 +206,11 @@ module Measurement
|
|
173
206
|
|
174
207
|
def method_missing(method, *args) # :nodoc:
|
175
208
|
if method.to_s =~ /^(as|in)_(.*)/
|
176
|
-
|
177
|
-
if
|
178
|
-
to_s(
|
209
|
+
unit = $2
|
210
|
+
if unit =~ /and/
|
211
|
+
to_s(unit, *args)
|
179
212
|
else
|
180
|
-
as(
|
213
|
+
as(unit.to_sym, *args)
|
181
214
|
end
|
182
215
|
else
|
183
216
|
super
|
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.1"
|
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-02-
|
9
|
+
s.date = %q{2010-02-28}
|
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"]
|
@@ -1,6 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Measurement::Base do
|
4
|
+
describe '::base' do
|
5
|
+
it 'should define to_measurement on Fixnum and Float' do
|
6
|
+
Length
|
7
|
+
1.to_length.should be_a(Length)
|
8
|
+
1.to_length.to_f.should == 1.0
|
9
|
+
1.5.to_length.should be_a(Length)
|
10
|
+
1.5.to_length.to_f.should == 1.5
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should define to_measurement on String' do
|
14
|
+
Length
|
15
|
+
"10cm".to_length.should be_a(Length)
|
16
|
+
"10cm".to_length.to_s(:metre, 1).should == "0.1m"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
4
20
|
describe '::parse' do
|
5
21
|
it 'should parse in the base unit if no unit is specified' do
|
6
22
|
Length.parse('113').to_f.should == 113.0
|
@@ -33,6 +49,30 @@ describe Measurement::Base do
|
|
33
49
|
end
|
34
50
|
end
|
35
51
|
|
52
|
+
describe 'operators' do
|
53
|
+
before do
|
54
|
+
@length_1 = Length.new(1)
|
55
|
+
@length_2 = Length.new(2)
|
56
|
+
end
|
57
|
+
|
58
|
+
%w(+ - / *).each do |operator|
|
59
|
+
it 'should return a new object of the same type' do
|
60
|
+
@length_1.send(operator, @length_2).should be_a(Length)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should perform the operator' do
|
64
|
+
@value = @length_1.to_f.send(operator, @length_2.to_f)
|
65
|
+
@length_1.send(operator, @length_2).to_f.should == @value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#<=>' do
|
71
|
+
it 'should return the difference between the objects' do
|
72
|
+
(Length.new(1) <=> Length.new(2)).should == (1.0 <=> 2.0)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
36
76
|
describe '#method_missing' do
|
37
77
|
it 'should call as if passed in_scale' do
|
38
78
|
Length.new(10).in_cm.should == Length.new(10).as(:cm)
|
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:
|
4
|
+
version: 0.2.1
|
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-02-
|
12
|
+
date: 2010-02-28 00:00:00 +13:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|