m9t 0.1.12 → 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/README.rdoc +38 -0
- data/Rakefile +12 -27
- data/lib/m9t.rb +1 -8
- data/lib/m9t/base.rb +78 -16
- data/lib/m9t/direction.rb +16 -10
- data/lib/m9t/distance.rb +6 -65
- data/lib/m9t/pressure.rb +7 -31
- data/lib/m9t/speed.rb +9 -75
- data/lib/m9t/temperature.rb +9 -15
- data/lib/m9t/version.rb +11 -0
- data/test/direction_test.rb +26 -18
- data/test/distance_test.rb +67 -45
- data/test/speed_test.rb +20 -7
- data/test/temperature_test.rb +21 -6
- metadata +24 -22
data/README.rdoc
CHANGED
@@ -11,6 +11,44 @@ The emphasis is on:
|
|
11
11
|
* coherent interface,
|
12
12
|
* ease of translation (using i18n).
|
13
13
|
|
14
|
+
== Internals
|
15
|
+
|
16
|
+
Internally, values are stored in SI units, with the exception of temperature:
|
17
|
+
* distance - meters,
|
18
|
+
* direction - degrees,
|
19
|
+
* speed - meters per second,
|
20
|
+
* temperature - degrees celcius,
|
21
|
+
* weight - kilograms.
|
22
|
+
|
23
|
+
== Interface
|
24
|
+
|
25
|
+
new: accepts the S.I. unit as a parameter:
|
26
|
+
|
27
|
+
height = M9t::Distance.new(1.75)
|
28
|
+
|
29
|
+
to_f: returns the decimal value(s):
|
30
|
+
|
31
|
+
height.to_f -> 1.75
|
32
|
+
|
33
|
+
other units:
|
34
|
+
there are class methods named after each known unit,
|
35
|
+
which take values in that unit
|
36
|
+
(actually, they are defined as needed):
|
37
|
+
|
38
|
+
marathon = M9t::Distance.miles(26.21875)
|
39
|
+
marathon.to_f -> 42194.988
|
40
|
+
|
41
|
+
to_s: returns a localized string with units:
|
42
|
+
|
43
|
+
I18n.locale = :it
|
44
|
+
puts M9t::Distance.new(3).to_s -> '3 metri'
|
45
|
+
|
46
|
+
=== Class methods for conversion
|
47
|
+
|
48
|
+
Methods are available for conversion between any pair of units:
|
49
|
+
|
50
|
+
M9t::Distance.miles_to_meters(26.21875) -> 42194.988
|
51
|
+
|
14
52
|
== Other Software
|
15
53
|
|
16
54
|
* ruby-units
|
data/Rakefile
CHANGED
@@ -1,42 +1,20 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require 'rake/gempackagetask'
|
3
2
|
require 'rake/rdoctask'
|
4
3
|
require 'rake/testtask'
|
5
4
|
require 'rake/clean'
|
6
5
|
|
7
|
-
$:.unshift(File.dirname(__FILE__) + '/lib')
|
8
|
-
require
|
6
|
+
$:.unshift( File.dirname(__FILE__) + '/lib' )
|
7
|
+
require "bundler/version"
|
9
8
|
|
10
9
|
RDOC_OPTS = ['--quiet', '--title', 'm9t: Measurement units', '--main', 'README.rdoc', '--inline-source']
|
11
10
|
CLEAN.include 'doc'
|
12
11
|
|
13
12
|
task :default => :test
|
14
13
|
|
15
|
-
spec = Gem::Specification.new do |s|
|
16
|
-
s.name = 'm9t'
|
17
|
-
s.summary = 'Classes for handling measurement units'
|
18
|
-
s.description = 'Classes for handling measurement units, conversions and translations'
|
19
|
-
s.version = M9t::VERSION::STRING
|
20
|
-
|
21
|
-
s.homepage = 'http://github.com/joeyates/m9t'
|
22
|
-
s.author = 'Joe Yates'
|
23
|
-
s.email = 'joe.g.yates@gmail.com'
|
24
|
-
|
25
|
-
s.files = ['README.rdoc', 'COPYING', 'Rakefile'] + FileList['{lib,test}/**/*.rb'] + FileList['locales/**/*.{rb,yml}']
|
26
|
-
s.require_paths = ['lib']
|
27
|
-
s.add_dependency('i18n', '>= 0.3.5')
|
28
|
-
|
29
|
-
s.has_rdoc = true
|
30
|
-
s.rdoc_options += RDOC_OPTS
|
31
|
-
s.extra_rdoc_files = ['README.rdoc', 'COPYING']
|
32
|
-
|
33
|
-
s.test_file = 'test/test_all.rb'
|
34
|
-
end
|
35
|
-
|
36
14
|
Rake::TestTask.new do |t|
|
37
|
-
t.libs
|
15
|
+
t.libs << 'test'
|
38
16
|
t.test_files = FileList['test/*_test.rb']
|
39
|
-
t.verbose
|
17
|
+
t.verbose = true
|
40
18
|
end
|
41
19
|
|
42
20
|
Rake::RDocTask.new do |rdoc|
|
@@ -46,5 +24,12 @@ Rake::RDocTask.new do |rdoc|
|
|
46
24
|
rdoc.rdoc_files.add ['README.rdoc', 'COPYING', 'lib/**/*.rb']
|
47
25
|
end
|
48
26
|
|
49
|
-
|
27
|
+
desc "Build the gem"
|
28
|
+
task :build do
|
29
|
+
system "gem build m9t.gemspec"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Publish a new version of the gem"
|
33
|
+
task :release => :build do
|
34
|
+
system "gem push m9t-#{M9t::VERSION}"
|
50
35
|
end
|
data/lib/m9t.rb
CHANGED
@@ -27,6 +27,7 @@ require 'i18n'
|
|
27
27
|
|
28
28
|
locales_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'locales'))
|
29
29
|
I18n.load_path += Dir.glob("#{ locales_path }/*.yml")
|
30
|
+
I18n.reload!
|
30
31
|
|
31
32
|
Dir[File.dirname(__FILE__) + '/m9t/*.rb'].each do |file|
|
32
33
|
require file
|
@@ -34,14 +35,6 @@ end
|
|
34
35
|
|
35
36
|
module M9t
|
36
37
|
|
37
|
-
module VERSION #:nodoc:
|
38
|
-
MAJOR = 0
|
39
|
-
MINOR = 1
|
40
|
-
TINY = 12
|
41
|
-
|
42
|
-
STRING = [MAJOR, MINOR, TINY].join('.')
|
43
|
-
end
|
44
|
-
|
45
38
|
# Base class for all M9t exceptions
|
46
39
|
class M9tError < StandardError
|
47
40
|
end
|
data/lib/m9t/base.rb
CHANGED
@@ -6,10 +6,49 @@ module M9t
|
|
6
6
|
|
7
7
|
module Base
|
8
8
|
|
9
|
-
def self.
|
9
|
+
def self.generate_conversions(klass)
|
10
|
+
klass.instance_eval do |klass|
|
11
|
+
def convert(from, to, value)
|
12
|
+
value * self::CONVERSIONS[from] / self::CONVERSIONS[to]
|
13
|
+
end
|
10
14
|
|
11
|
-
|
15
|
+
def method_missing(name, *args, &block)
|
16
|
+
# Define class conversion methods as required
|
17
|
+
if name.to_s =~ /^(\w+)_to_(\w+)$/
|
18
|
+
return send(name, args[0]) if define_conversion($1, $2)
|
19
|
+
end
|
20
|
+
return send(name, args[0]) if define_constructor(name)
|
21
|
+
raise "Method '#{ name }' unknown" # TODO use standard exception
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def define_conversion(from, to)
|
27
|
+
return false if not self::CONVERSIONS[from.to_sym]
|
28
|
+
return false if not self::CONVERSIONS[to.to_sym]
|
29
|
+
self.class.instance_exec do
|
30
|
+
define_method("#{ from }_to_#{ to }") do |value|
|
31
|
+
convert(from.to_sym, to.to_sym, value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
# Define klass.unit(value) which converts the parameter
|
38
|
+
# from the unit and returns an instance
|
39
|
+
def define_constructor(name)
|
40
|
+
return false if not self::CONVERSIONS[name.to_sym]
|
41
|
+
self.class.instance_exec do
|
42
|
+
define_method( name.to_sym ) do | *args |
|
43
|
+
new( args[ 0 ].to_f * self::CONVERSIONS[ name ] )
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
12
49
|
|
50
|
+
def self.add_options(klass)
|
51
|
+
klass.instance_eval do
|
13
52
|
# Make sure derived classes get the extra methods
|
14
53
|
def inherited(sub) #:nodoc:
|
15
54
|
sub.instance_eval do
|
@@ -33,43 +72,66 @@ module M9t
|
|
33
72
|
name.downcase.split('::')[1]
|
34
73
|
end
|
35
74
|
|
75
|
+
def default_unit
|
76
|
+
self::DEFAULT_OPTIONS[:units]
|
77
|
+
end
|
78
|
+
|
36
79
|
reset_options!
|
37
80
|
end
|
38
|
-
|
39
81
|
end
|
40
82
|
|
41
83
|
# Adds methods for handling options
|
42
84
|
def self.included(base) #:nodoc:
|
43
85
|
M9t::Base.add_options(base)
|
86
|
+
M9t::Base.generate_conversions(base)
|
44
87
|
end
|
45
88
|
|
46
89
|
attr_reader :value, :options
|
90
|
+
alias :to_f :value
|
91
|
+
|
92
|
+
def initialize( value )
|
93
|
+
@value = value.to_f
|
94
|
+
end
|
47
95
|
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
96
|
+
# define conversion instance methods as required
|
97
|
+
def method_missing(name, *args, &block)
|
98
|
+
if name.to_s =~ /^to_(\w+)$/
|
99
|
+
return send(name, @value) if define_conversion($1)
|
100
|
+
end
|
101
|
+
raise "Method '#{ name }' unknown" # TODO use standard exception
|
53
102
|
end
|
54
103
|
|
55
104
|
# Returns the string representation of the measurement,
|
56
105
|
# taking into account locale, desired units and abbreviation.
|
57
|
-
def to_s
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
106
|
+
def to_s( options = {} )
|
107
|
+
options = self.class.options.merge( options )
|
108
|
+
units_error( options[ :units ] ) if not self.class::CONVERSIONS.has_key?( options[ :units ] )
|
109
|
+
value_in_units = self.send("to_#{ options[:units] }")
|
110
|
+
localized_value = I18n.localize_float(value_in_units, {:format => "%0.#{ options[:precision] }f"})
|
111
|
+
|
112
|
+
key = 'units.' + self.class.measurement_name + '.' + options[:units].to_s
|
113
|
+
options[:abbreviated] ? key += '.abbreviated' : key += '.full'
|
63
114
|
unit = I18n.t(key, {:count => value_in_units})
|
64
115
|
|
65
|
-
"#{ localized_value }%s#{ unit }" % (
|
116
|
+
"#{ localized_value }%s#{ unit }" % (options[:abbreviated] ? '' : ' ')
|
66
117
|
end
|
67
118
|
|
68
119
|
private
|
69
120
|
|
70
121
|
def units_error(units)
|
71
|
-
raise M9t::UnitError.new("Unknown units '#{ units }'. Known: #{ self.class::
|
122
|
+
raise M9t::UnitError.new("Unknown units '#{ units }'. Known: #{ self.class::CONVERSIONS.keys.collect{|unit| unit.to_s}.join(', ') }")
|
72
123
|
end
|
124
|
+
|
125
|
+
def define_conversion(to)
|
126
|
+
return false if not self.class::CONVERSIONS[to.to_sym]
|
127
|
+
self.class.instance_exec do
|
128
|
+
define_method("to_#{ to }") do
|
129
|
+
self.class.convert(self.class.default_unit, to.to_sym, self.to_f)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
true
|
133
|
+
end
|
134
|
+
|
73
135
|
end
|
74
136
|
|
75
137
|
end
|
data/lib/m9t/direction.rb
CHANGED
@@ -7,7 +7,10 @@ module M9t
|
|
7
7
|
# Represents a geographical direction
|
8
8
|
class Direction
|
9
9
|
DEFAULT_OPTIONS = {:units => :degrees, :abbreviated => false, :decimals => 5}
|
10
|
-
|
10
|
+
CONVERSIONS = {
|
11
|
+
:degrees => 1.0,
|
12
|
+
:compass => nil,
|
13
|
+
}
|
11
14
|
|
12
15
|
# Conversions
|
13
16
|
CIRCLE = 360.0
|
@@ -17,18 +20,17 @@ module M9t
|
|
17
20
|
|
18
21
|
class << self
|
19
22
|
|
20
|
-
# Identity conversion. Simply returns the supplied number
|
21
|
-
def to_degrees(degrees)
|
22
|
-
degrees.to_f
|
23
|
-
end
|
24
|
-
|
25
23
|
# Given a value in degrees, returns the nearest (localized) compass direction
|
26
24
|
# M9t::Directions.to_compass(42) => 'NE'
|
27
|
-
def
|
25
|
+
def degrees_to_compass(degrees)
|
28
26
|
sector = (normalize(degrees) / COMPASS_SECTOR_DEGREES).round
|
29
27
|
I18n.t(self.measurement_name + '.sectors')[sector]
|
30
28
|
end
|
31
29
|
|
30
|
+
def compass_to_degrees(compass_direction)
|
31
|
+
compass(compass_direction).to_f
|
32
|
+
end
|
33
|
+
|
32
34
|
# Accepts a localized compass direction (e.g. 'N') and returns the equivalent M9t::Direction
|
33
35
|
# M9t::Direction.compass('NE') => #<M9t::Direction:0xb76cc750 @value=45.0, @options={:units=>:degrees, :decimals=>5, :abbreviated=>false}>
|
34
36
|
def compass(compass_direction)
|
@@ -53,14 +55,18 @@ module M9t
|
|
53
55
|
end
|
54
56
|
|
55
57
|
# Handles the special case where compass directions are the desired output.
|
56
|
-
def to_s
|
57
|
-
if
|
58
|
-
Direction.
|
58
|
+
def to_s( options = {} )
|
59
|
+
if options[:units] == :compass
|
60
|
+
Direction.degrees_to_compass(@value)
|
59
61
|
else
|
60
62
|
super
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
66
|
+
def to_compass
|
67
|
+
self.class.degrees_to_compass(@value)
|
68
|
+
end
|
69
|
+
|
64
70
|
end
|
65
71
|
|
66
72
|
end
|
data/lib/m9t/distance.rb
CHANGED
@@ -8,76 +8,17 @@ module M9t
|
|
8
8
|
# Represents a distance
|
9
9
|
class Distance
|
10
10
|
DEFAULT_OPTIONS = {:units => :meters, :abbreviated => false, :precision => 5}
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
CONVERSIONS = {
|
12
|
+
:meters => 1.0,
|
13
|
+
:kilometers => 1000.0,
|
14
|
+
:feet => 0.3048,
|
15
|
+
:miles => 1609.344
|
16
|
+
}
|
17
17
|
|
18
18
|
include M9t::Base
|
19
19
|
|
20
|
-
class << self
|
21
|
-
|
22
|
-
# Alias for new
|
23
|
-
def meters(*args)
|
24
|
-
new(*args)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Accepts a value in kilometers and returns the equivalent M9t::Distance
|
28
|
-
def kilometers(km, options = {})
|
29
|
-
new(km.to_f * KILOMETER, options)
|
30
|
-
end
|
31
|
-
|
32
|
-
# Accepts a value in miles and returns the equivalent M9t::Distance
|
33
|
-
def miles(miles, options = {})
|
34
|
-
new(miles.to_f * MILE, options)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Accepts a value in miles and returns the equivalent M9t::Distance
|
38
|
-
def feet(feet, options = {})
|
39
|
-
new(feet.to_f * FOOT, options)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Identity conversion. Simply returns the supplied number
|
43
|
-
def to_meters(meters)
|
44
|
-
meters.to_f
|
45
|
-
end
|
46
|
-
|
47
|
-
# Converts meters into kilometers
|
48
|
-
def to_kilometers(meters)
|
49
|
-
meters.to_f / KILOMETER
|
50
|
-
end
|
51
|
-
|
52
|
-
# Converts meters into miles
|
53
|
-
def to_miles(meters)
|
54
|
-
meters.to_f / MILE
|
55
|
-
end
|
56
|
-
|
57
|
-
# Converts meters into miles
|
58
|
-
def to_feet(meters)
|
59
|
-
meters.to_f / FOOT
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
20
|
alias :to_meters :value
|
65
21
|
|
66
|
-
# Returns the value converted to kilometers
|
67
|
-
def to_kilometers
|
68
|
-
self.class.to_kilometers(@value)
|
69
|
-
end
|
70
|
-
|
71
|
-
# Returns the value converted to miles
|
72
|
-
def to_miles
|
73
|
-
self.class.to_miles(@value)
|
74
|
-
end
|
75
|
-
|
76
|
-
# Returns the value converted to feet
|
77
|
-
def to_feet
|
78
|
-
self.class.to_feet(@value)
|
79
|
-
end
|
80
|
-
|
81
22
|
end
|
82
23
|
|
83
24
|
end
|
data/lib/m9t/pressure.rb
CHANGED
@@ -8,40 +8,16 @@ module M9t
|
|
8
8
|
# Represents atmospheric (or other) pressure
|
9
9
|
class Pressure
|
10
10
|
DEFAULT_OPTIONS = {:units => :bar, :abbreviated => false, :precision => 5}
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
CONVERSIONS = {
|
12
|
+
:bar => 1.0,
|
13
|
+
:pascals => 0.00001,
|
14
|
+
:hectopascals => 0.001,
|
15
|
+
:kilopascals => 0.01,
|
16
|
+
:inches_of_mercury => 3386.389 * 0.00001
|
17
|
+
}
|
18
18
|
|
19
19
|
include M9t::Base
|
20
20
|
|
21
|
-
def Pressure.hectopascals(hectopascals)
|
22
|
-
new(hectopascals * HECTOPASCAL)
|
23
|
-
end
|
24
|
-
|
25
|
-
def Pressure.inches_of_mercury(inches_of_mercury)
|
26
|
-
new(inches_of_mercury * INCH_OF_MERCURY)
|
27
|
-
end
|
28
|
-
|
29
|
-
def Pressure.to_inches_of_mercury(bar)
|
30
|
-
bar / INCH_OF_MERCURY
|
31
|
-
end
|
32
|
-
|
33
|
-
def Pressure.to_bar(bar)
|
34
|
-
bar.to_f
|
35
|
-
end
|
36
|
-
|
37
|
-
def to_inches_of_mercury
|
38
|
-
Pressure.to_inches_of_mercury(@value)
|
39
|
-
end
|
40
|
-
|
41
|
-
def to_bar
|
42
|
-
Pressure.to_bar(@value)
|
43
|
-
end
|
44
|
-
|
45
21
|
end
|
46
22
|
|
47
23
|
end
|
data/lib/m9t/speed.rb
CHANGED
@@ -8,88 +8,22 @@ module M9t
|
|
8
8
|
# Represents a speed
|
9
9
|
class Speed
|
10
10
|
DEFAULT_OPTIONS = {:units => :meters_per_second, :abbreviated => false, :precision => 5}
|
11
|
-
KNOWN_UNITS = [:meters_per_second, :kilometers_per_hour, :miles_per_hour, :knots]
|
12
|
-
|
13
|
-
# Conversions
|
14
11
|
SECONDS_PER_HOUR = 60.0 * 60
|
15
|
-
|
16
|
-
|
12
|
+
KMH = M9t::Distance::CONVERSIONS[:kilometers] / SECONDS_PER_HOUR
|
13
|
+
MPH = M9t::Distance::CONVERSIONS[:miles] / SECONDS_PER_HOUR
|
17
14
|
KNOTS_TO_KMH = 1.852
|
18
|
-
|
15
|
+
KNOTS = KNOTS_TO_KMH / SECONDS_PER_HOUR * M9t::Distance::CONVERSIONS[:kilometers]
|
16
|
+
CONVERSIONS = {
|
17
|
+
:meters_per_second => 1.0,
|
18
|
+
:kilometers_per_hour => KMH,
|
19
|
+
:miles_per_hour => MPH,
|
20
|
+
:knots => KNOTS
|
21
|
+
}
|
19
22
|
|
20
23
|
include M9t::Base
|
21
24
|
|
22
|
-
class << self
|
23
|
-
|
24
|
-
# Accepts kilometers per hour and returns a M9t::Speed instance
|
25
|
-
def kilometers_per_hour(kmh, options = {})
|
26
|
-
new(kmh.to_f / MS_TO_KMH, options)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Accepts miles per hour and returns a M9t::Speed instance
|
30
|
-
def miles_per_hour(mph, options = {})
|
31
|
-
new(mph.to_f / MS_TO_MPH, options)
|
32
|
-
end
|
33
|
-
|
34
|
-
# Accepts knots and returns a M9t::Speed instance
|
35
|
-
def knots(knots, options = {})
|
36
|
-
new(knots.to_f / MS_TO_KNOTS, options)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Alias for new
|
40
|
-
def meters_per_second(*args)
|
41
|
-
new(*args)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Identity conversion. Simply returns the supplied number
|
45
|
-
def to_meters_per_second(mps)
|
46
|
-
mps.to_f
|
47
|
-
end
|
48
|
-
|
49
|
-
# Converts meters per second to kilometers per hour
|
50
|
-
def to_kilometers_per_hour(mps)
|
51
|
-
mps.to_f * MS_TO_KMH
|
52
|
-
end
|
53
|
-
|
54
|
-
# Converts meters per second to miles per hour
|
55
|
-
def to_miles_per_hour(mps)
|
56
|
-
mps.to_f * MS_TO_MPH
|
57
|
-
end
|
58
|
-
|
59
|
-
# Converts meters per second to knots
|
60
|
-
def to_knots(mps)
|
61
|
-
mps.to_f * MS_TO_KNOTS
|
62
|
-
end
|
63
|
-
|
64
|
-
# Converts knots to kilometers hour
|
65
|
-
def knots_to_kilometers_per_hour(knots)
|
66
|
-
to_kilometers_per_hour(knots.to_f / MS_TO_KNOTS)
|
67
|
-
end
|
68
|
-
|
69
|
-
# Converts knots to kilometers hour
|
70
|
-
def kilometers_per_hour_to_knots(knh)
|
71
|
-
to_knots(kmh.to_f / MS_TO_KMH)
|
72
|
-
end
|
73
|
-
|
74
|
-
end
|
75
|
-
|
76
25
|
alias :to_meters_per_second :value
|
77
26
|
|
78
|
-
# Returns the value converted to kilometers per hour
|
79
|
-
def to_kilometers_per_hour
|
80
|
-
self.class.to_kilometers_per_hour(@value)
|
81
|
-
end
|
82
|
-
|
83
|
-
# Returns the value converted to miles per hour
|
84
|
-
def to_miles_per_hour
|
85
|
-
self.class.to_miles_per_hour(@value)
|
86
|
-
end
|
87
|
-
|
88
|
-
# Returns the value converted to miles per hour
|
89
|
-
def to_knots
|
90
|
-
self.class.to_knots(@value)
|
91
|
-
end
|
92
|
-
|
93
27
|
end
|
94
28
|
|
95
29
|
end
|
data/lib/m9t/temperature.rb
CHANGED
@@ -9,7 +9,11 @@ module M9t
|
|
9
9
|
# Using degrees (celcius), not kelvin, as default unit
|
10
10
|
class Temperature
|
11
11
|
DEFAULT_OPTIONS = {:units => :degrees, :abbreviated => false, :precision => 5}
|
12
|
-
|
12
|
+
CONVERSIONS = {
|
13
|
+
:degrees => 1.0,
|
14
|
+
:kelvin => nil,
|
15
|
+
:fahrenheit => nil
|
16
|
+
}
|
13
17
|
|
14
18
|
# Conversions
|
15
19
|
ABSOLUTE_ZERO = -273.15
|
@@ -18,23 +22,13 @@ module M9t
|
|
18
22
|
|
19
23
|
class << self
|
20
24
|
|
21
|
-
# Alias for new
|
22
|
-
def degrees(*args)
|
23
|
-
new(*args)
|
24
|
-
end
|
25
|
-
|
26
25
|
# Accepts a value in kelvin and returns the equivalent M9t::Temperature
|
27
|
-
def kelvin(kelvin
|
28
|
-
new(kelvin.to_f + ABSOLUTE_ZERO
|
29
|
-
end
|
30
|
-
|
31
|
-
def fahrenheit(fahrenheit, options = {})
|
32
|
-
new(fahrenheit_to_degrees(fahrenheit), options)
|
26
|
+
def kelvin( kelvin )
|
27
|
+
new( kelvin.to_f + ABSOLUTE_ZERO )
|
33
28
|
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
degrees.to_f
|
30
|
+
def fahrenheit( fahrenheit )
|
31
|
+
new( fahrenheit_to_degrees( fahrenheit ) )
|
38
32
|
end
|
39
33
|
|
40
34
|
# Converts degrees to kelvin
|
data/lib/m9t/version.rb
ADDED
data/test/direction_test.rb
CHANGED
@@ -43,16 +43,16 @@ class TestM9tDirection < Test::Unit::TestCase
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_to_degrees_identity
|
46
|
-
assert_equal(45, M9t::Direction.
|
46
|
+
assert_equal(45, M9t::Direction.degrees_to_degrees(45))
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
50
|
-
assert_equal('N', M9t::Direction.
|
51
|
-
assert_equal('NE', M9t::Direction.
|
52
|
-
assert_equal('E', M9t::Direction.
|
53
|
-
assert_equal('ESE', M9t::Direction.
|
49
|
+
def test_degrees_to_compass
|
50
|
+
assert_equal('N', M9t::Direction.degrees_to_compass(0))
|
51
|
+
assert_equal('NE', M9t::Direction.degrees_to_compass(42)) # Quantizing up
|
52
|
+
assert_equal('E', M9t::Direction.degrees_to_compass(93)) # Quantizing down
|
53
|
+
assert_equal('ESE', M9t::Direction.degrees_to_compass(113)) # 16ths
|
54
54
|
I18n.locale = :it
|
55
|
-
assert_equal('O', M9t::Direction.
|
55
|
+
assert_equal('O', M9t::Direction.degrees_to_compass(270))
|
56
56
|
end
|
57
57
|
|
58
58
|
def test_compass
|
@@ -60,32 +60,40 @@ class TestM9tDirection < Test::Unit::TestCase
|
|
60
60
|
assert_equal(247.5, M9t::Direction.compass('WSW').value)
|
61
61
|
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
def test_unknown_units
|
66
|
-
assert_raises(M9t::UnitError) { M9t::Direction.new(10, {:units => :foos}) }
|
63
|
+
def test_compass_to_degrees
|
64
|
+
assert_equal(247.5, M9t::Direction.compass_to_degrees('WSW'))
|
67
65
|
end
|
68
66
|
|
67
|
+
# Instance methods
|
68
|
+
|
69
69
|
def test_to_s_not_abbreviated_singular
|
70
|
-
|
70
|
+
direction = M9t::Direction.new( 1 )
|
71
|
+
|
72
|
+
assert_equal '1 degree', direction.to_s
|
71
73
|
I18n.locale = :it
|
72
|
-
assert_equal '1 grado',
|
74
|
+
assert_equal '1 grado', direction.to_s
|
73
75
|
end
|
74
76
|
|
75
77
|
def test_to_s_not_abbreviated_plural
|
76
|
-
|
78
|
+
direction = M9t::Direction.new( 135 )
|
79
|
+
|
80
|
+
assert_equal '135 degrees', direction.to_s
|
77
81
|
I18n.locale = :it
|
78
|
-
assert_equal '135 gradi',
|
82
|
+
assert_equal '135 gradi', direction.to_s
|
79
83
|
end
|
80
84
|
|
81
85
|
def test_to_s_abbreviated
|
82
|
-
|
86
|
+
direction = M9t::Direction.new( 135 )
|
87
|
+
|
88
|
+
assert_equal '135°', direction.to_s( :abbreviated => true )
|
83
89
|
end
|
84
90
|
|
85
91
|
def test_compass_units
|
86
|
-
|
92
|
+
direction = M9t::Direction.new( 225 )
|
93
|
+
|
94
|
+
assert_equal 'SW', direction.to_s( :units => :compass )
|
87
95
|
I18n.locale = :it
|
88
|
-
assert_equal 'SO',
|
96
|
+
assert_equal 'SO', direction.to_s( :units => :compass )
|
89
97
|
end
|
90
98
|
|
91
99
|
def test_handles_string_leading_zero
|
data/test/distance_test.rb
CHANGED
@@ -14,17 +14,19 @@ class TestM9tDistance < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
# Basic use
|
16
16
|
def test_singular
|
17
|
-
distance = M9t::Distance.new(1
|
17
|
+
distance = M9t::Distance.new( 1 )
|
18
18
|
I18n.locale = :en
|
19
|
-
|
19
|
+
|
20
|
+
assert_equal('1 meter', distance.to_s( :precision => 0 ) )
|
20
21
|
end
|
21
22
|
|
22
23
|
def test_plural
|
23
|
-
distance = M9t::Distance.new(10
|
24
|
+
distance = M9t::Distance.new( 10 )
|
25
|
+
|
24
26
|
I18n.locale = :en
|
25
|
-
assert_equal('10 meters', distance.to_s)
|
27
|
+
assert_equal( '10 meters', distance.to_s( :precision => 0 ) )
|
26
28
|
I18n.locale = :it
|
27
|
-
assert_equal('10 metri', distance.to_s)
|
29
|
+
assert_equal( '10 metri', distance.to_s( :precision => 0 ) )
|
28
30
|
end
|
29
31
|
|
30
32
|
# Class methods
|
@@ -35,24 +37,38 @@ class TestM9tDistance < Test::Unit::TestCase
|
|
35
37
|
assert_equal('distance', M9t::Distance.measurement_name)
|
36
38
|
end
|
37
39
|
|
38
|
-
#
|
39
|
-
|
40
|
-
|
40
|
+
# Construction
|
41
|
+
# ...from meters
|
42
|
+
def test_new
|
43
|
+
assert_equal(0.3, M9t::Distance.new(0.3).to_f)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_class_meters
|
47
|
+
assert_equal(0.3, M9t::Distance.meters(0.3).to_f)
|
41
48
|
end
|
42
49
|
|
43
|
-
|
44
|
-
|
50
|
+
# ...from other units
|
51
|
+
def test_class_kilometers
|
52
|
+
assert_in_delta(300.0, M9t::Distance.kilometers(0.3).to_f, 0.00001)
|
45
53
|
end
|
46
54
|
|
47
|
-
|
48
|
-
|
49
|
-
|
55
|
+
def test_class_miles
|
56
|
+
assert_in_delta(1609.344, M9t::Distance.miles(1).to_f, 0.00001)
|
57
|
+
assert_in_delta(42194.988, M9t::Distance.miles(26.21875).to_f, 0.00001)
|
50
58
|
end
|
51
59
|
|
52
|
-
|
53
|
-
|
60
|
+
# Conversion class methods
|
61
|
+
# ...to other units
|
62
|
+
def test_class_meters_to_kilometers
|
63
|
+
assert_equal(0.0003, M9t::Distance.meters_to_kilometers(0.3))
|
54
64
|
end
|
55
65
|
|
66
|
+
def test_class_miles_to_kilometers
|
67
|
+
assert_in_delta(42.194988, M9t::Distance.miles_to_kilometers(26.21875), 0.00001)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Default options
|
71
|
+
|
56
72
|
def test_default_options_set
|
57
73
|
assert_not_nil(M9t::Distance.options)
|
58
74
|
end
|
@@ -71,30 +87,20 @@ class TestM9tDistance < Test::Unit::TestCase
|
|
71
87
|
|
72
88
|
# Instance methods
|
73
89
|
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
def test_default_options_merged
|
79
|
-
distance = M9t::Distance.new(10, {:abbreviated => true})
|
80
|
-
assert_equal(:meters, distance.options[:units])
|
81
|
-
assert_equal(5, distance.options[:precision])
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_set_default_options_get_inherited
|
85
|
-
M9t::Distance.options[:precision] = 0
|
86
|
-
distance = M9t::Distance.new(10)
|
87
|
-
assert_equal(0, distance.options[:precision])
|
88
|
-
end
|
89
|
-
|
90
|
-
def test_to_meters
|
90
|
+
# Conversion
|
91
|
+
def test_instance_to_meters
|
91
92
|
assert_equal(0.3, M9t::Distance.new(0.3).to_meters)
|
92
93
|
end
|
93
94
|
|
94
|
-
def
|
95
|
+
def test_instance_to_kilometers
|
95
96
|
assert_equal(0.0003, M9t::Distance.new(0.3).to_kilometers)
|
96
97
|
end
|
97
98
|
|
99
|
+
def test_instance_to_kilometers
|
100
|
+
assert_in_delta(0.98425, M9t::Distance.new(0.3).to_feet, 0.00001)
|
101
|
+
end
|
102
|
+
|
103
|
+
# to_s
|
98
104
|
def test_to_s_singular
|
99
105
|
assert_equal('1.00000 meter', M9t::Distance.new(1).to_s)
|
100
106
|
end
|
@@ -103,40 +109,56 @@ class TestM9tDistance < Test::Unit::TestCase
|
|
103
109
|
assert_equal('0.30000 meters', M9t::Distance.new(0.3).to_s)
|
104
110
|
end
|
105
111
|
|
112
|
+
# i18n
|
106
113
|
def test_to_s_plural_abbreviated
|
107
|
-
distance = M9t::Distance.new(10
|
114
|
+
distance = M9t::Distance.new( 10 )
|
108
115
|
I18n.locale = :en
|
109
|
-
assert_equal('10m', distance.to_s
|
116
|
+
assert_equal( '10m', distance.to_s( :abbreviated => true,
|
117
|
+
:precision => 0 ) )
|
110
118
|
I18n.locale = :it
|
111
|
-
assert_equal('10m', distance.to_s
|
119
|
+
assert_equal( '10m', distance.to_s( :abbreviated => true,
|
120
|
+
:precision => 0 ) )
|
112
121
|
end
|
113
122
|
|
114
123
|
def test_to_s_abbreviated
|
115
|
-
|
124
|
+
distance = M9t::Distance.new( 0.3 )
|
125
|
+
|
126
|
+
assert_equal( '0.30000m', distance.to_s( :abbreviated => true ) )
|
116
127
|
end
|
117
128
|
|
118
129
|
def test_to_s_precision
|
119
|
-
|
130
|
+
distance = M9t::Distance.new( 0.3 )
|
131
|
+
|
132
|
+
assert_equal( '0.3m', distance.to_s( :precision => 1,
|
133
|
+
:abbreviated => true ) )
|
120
134
|
end
|
121
135
|
|
122
136
|
def test_to_s_kilometers
|
123
|
-
|
137
|
+
distance = M9t::Distance.new( 156003 )
|
138
|
+
|
139
|
+
assert_equal( '156.0 kilometers', distance.to_s( :precision => 1,
|
140
|
+
:units => :kilometers ) )
|
124
141
|
end
|
125
142
|
|
126
143
|
def test_miles_singular
|
127
|
-
|
144
|
+
marathon = M9t::Distance.miles( 26.21875 )
|
128
145
|
I18n.locale = :en
|
129
|
-
assert_equal(
|
146
|
+
assert_equal( '26 miles', marathon.to_s( :units => :miles,
|
147
|
+
:precision => 0 ) )
|
130
148
|
I18n.locale = :it
|
131
|
-
assert_equal(
|
149
|
+
assert_equal( '26 miglia', marathon.to_s( :units => :miles,
|
150
|
+
:precision => 0 ) )
|
132
151
|
end
|
133
152
|
|
134
153
|
def test_to_s_miles_plural
|
135
|
-
|
154
|
+
ten_km = M9t::Distance.new( 10000 )
|
155
|
+
|
136
156
|
I18n.locale = :en
|
137
|
-
assert_equal('6.2 miles',
|
157
|
+
assert_equal( '6.2 miles', ten_km.to_s( :units => :miles,
|
158
|
+
:precision => 1 ) )
|
138
159
|
I18n.locale = :it
|
139
|
-
assert_equal('6,2 miglia',
|
160
|
+
assert_equal( '6,2 miglia', ten_km.to_s( :units => :miles,
|
161
|
+
:precision => 1 ) )
|
140
162
|
end
|
141
163
|
|
142
164
|
end
|
data/test/speed_test.rb
CHANGED
@@ -28,7 +28,7 @@ class TestM9tSpeed < Test::Unit::TestCase
|
|
28
28
|
# conversion constants
|
29
29
|
|
30
30
|
def test_knot_conversion
|
31
|
-
assert_in_delta(
|
31
|
+
assert_in_delta(0.51444, M9t::Speed::KNOTS, 0.0001)
|
32
32
|
end
|
33
33
|
|
34
34
|
# input conversions
|
@@ -48,7 +48,7 @@ class TestM9tSpeed < Test::Unit::TestCase
|
|
48
48
|
# output conversions
|
49
49
|
|
50
50
|
def test_class_to_miles_per_hour
|
51
|
-
assert_in_delta(100.6621, M9t::Speed.
|
51
|
+
assert_in_delta(100.6621, M9t::Speed.meters_per_second_to_miles_per_hour(45), 0.0001)
|
52
52
|
end
|
53
53
|
|
54
54
|
# Instance methods
|
@@ -56,7 +56,11 @@ class TestM9tSpeed < Test::Unit::TestCase
|
|
56
56
|
# new
|
57
57
|
|
58
58
|
def test_unknown_units
|
59
|
-
|
59
|
+
speed = M9t::Speed.new( '010' )
|
60
|
+
|
61
|
+
assert_raises( M9t::UnitError ) do
|
62
|
+
speed.to_s( :units => :foos )
|
63
|
+
end
|
60
64
|
end
|
61
65
|
|
62
66
|
# output conversions
|
@@ -78,17 +82,26 @@ class TestM9tSpeed < Test::Unit::TestCase
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def test_to_s_precision
|
81
|
-
|
85
|
+
speed = M9t::Speed.new( 135 )
|
86
|
+
|
87
|
+
assert_equal '135 meters per second', speed.to_s( :precision => 0 )
|
82
88
|
end
|
83
89
|
|
84
90
|
def test_to_s_abbreviated
|
85
|
-
|
91
|
+
speed = M9t::Speed.new( 135 )
|
92
|
+
|
93
|
+
assert_equal '135m/s', speed.to_s( :abbreviated => true,
|
94
|
+
:precision => 0 )
|
86
95
|
end
|
87
96
|
|
88
97
|
def test_to_s_knots
|
89
|
-
|
98
|
+
speed = M9t::Speed.new( 135 )
|
99
|
+
|
100
|
+
assert_equal '262 knots', speed.to_s( :units => :knots,
|
101
|
+
:precision => 0 )
|
90
102
|
I18n.locale = :it
|
91
|
-
assert_equal '262 nodi',
|
103
|
+
assert_equal '262 nodi', speed.to_s( :units => :knots,
|
104
|
+
:precision => 0 )
|
92
105
|
end
|
93
106
|
|
94
107
|
end
|
data/test/temperature_test.rb
CHANGED
@@ -56,7 +56,11 @@ class TestM9tTemperature < Test::Unit::TestCase
|
|
56
56
|
# new
|
57
57
|
|
58
58
|
def test_unknown_units
|
59
|
-
|
59
|
+
temperature = M9t::Temperature.new( 1 )
|
60
|
+
|
61
|
+
assert_raises( M9t::UnitError ) do
|
62
|
+
temperature.to_s( :units => :foos )
|
63
|
+
end
|
60
64
|
end
|
61
65
|
|
62
66
|
# output conversions
|
@@ -78,18 +82,29 @@ class TestM9tTemperature < Test::Unit::TestCase
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def test_to_s_precision
|
81
|
-
|
85
|
+
temperature = M9t::Temperature.new( 135 )
|
86
|
+
|
87
|
+
assert_equal '135 degrees', temperature.to_s( :precision => 0 )
|
82
88
|
end
|
83
89
|
|
84
90
|
def test_to_s_abbreviated
|
85
|
-
|
86
|
-
|
91
|
+
temperature = M9t::Temperature.new( 135 )
|
92
|
+
|
93
|
+
assert_equal '135°C', temperature.to_s( :abbreviated => true,
|
94
|
+
:precision => 0 )
|
95
|
+
assert_equal '408.15K', temperature.to_s( :units => :kelvin,
|
96
|
+
:abbreviated => true,
|
97
|
+
:precision => 2 )
|
87
98
|
end
|
88
99
|
|
89
100
|
def test_to_s_kelvin
|
90
|
-
|
101
|
+
temperature = M9t::Temperature.new( 100 )
|
102
|
+
|
103
|
+
assert_equal '373.15 kelvin', temperature.to_s( :units => :kelvin,
|
104
|
+
:precision => 2 )
|
91
105
|
I18n.locale = :it
|
92
|
-
assert_equal '373,15 kelvin',
|
106
|
+
assert_equal '373,15 kelvin', temperature.to_s( :units => :kelvin,
|
107
|
+
:precision => 2 )
|
93
108
|
end
|
94
109
|
|
95
110
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: m9t
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 21
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
8
|
+
- 2
|
7
9
|
- 1
|
8
|
-
|
9
|
-
version: 0.1.12
|
10
|
+
version: 0.2.1
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Joe Yates
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date:
|
18
|
+
date: 2011-04-04 00:00:00 +01:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: i18n
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 25
|
27
30
|
segments:
|
28
31
|
- 0
|
29
32
|
- 3
|
@@ -37,62 +40,61 @@ executables: []
|
|
37
40
|
|
38
41
|
extensions: []
|
39
42
|
|
40
|
-
extra_rdoc_files:
|
41
|
-
|
42
|
-
- COPYING
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
43
45
|
files:
|
44
46
|
- README.rdoc
|
45
47
|
- COPYING
|
46
48
|
- Rakefile
|
47
|
-
- lib/m9t.rb
|
48
|
-
- lib/m9t/pressure.rb
|
49
|
-
- lib/m9t/speed.rb
|
50
49
|
- lib/m9t/base.rb
|
51
50
|
- lib/m9t/direction.rb
|
52
51
|
- lib/m9t/distance.rb
|
53
52
|
- lib/m9t/i18n.rb
|
53
|
+
- lib/m9t/pressure.rb
|
54
|
+
- lib/m9t/speed.rb
|
54
55
|
- lib/m9t/temperature.rb
|
55
|
-
-
|
56
|
+
- lib/m9t/version.rb
|
57
|
+
- lib/m9t.rb
|
56
58
|
- test/direction_test.rb
|
57
|
-
- test/i18n_test.rb
|
58
59
|
- test/distance_test.rb
|
60
|
+
- test/i18n_test.rb
|
61
|
+
- test/pressure_test.rb
|
62
|
+
- test/speed_test.rb
|
59
63
|
- test/temperature_test.rb
|
60
64
|
- test/test_all.rb
|
61
|
-
- test/speed_test.rb
|
62
|
-
- locales/it.yml
|
63
65
|
- locales/en.yml
|
66
|
+
- locales/it.yml
|
64
67
|
has_rdoc: true
|
65
68
|
homepage: http://github.com/joeyates/m9t
|
66
69
|
licenses: []
|
67
70
|
|
68
71
|
post_install_message:
|
69
|
-
rdoc_options:
|
70
|
-
|
71
|
-
- --title
|
72
|
-
- "m9t: Measurement units"
|
73
|
-
- --main
|
74
|
-
- README.rdoc
|
75
|
-
- --inline-source
|
72
|
+
rdoc_options: []
|
73
|
+
|
76
74
|
require_paths:
|
77
75
|
- lib
|
78
76
|
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
79
78
|
requirements:
|
80
79
|
- - ">="
|
81
80
|
- !ruby/object:Gem::Version
|
81
|
+
hash: 3
|
82
82
|
segments:
|
83
83
|
- 0
|
84
84
|
version: "0"
|
85
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
86
87
|
requirements:
|
87
88
|
- - ">="
|
88
89
|
- !ruby/object:Gem::Version
|
90
|
+
hash: 3
|
89
91
|
segments:
|
90
92
|
- 0
|
91
93
|
version: "0"
|
92
94
|
requirements: []
|
93
95
|
|
94
|
-
rubyforge_project:
|
95
|
-
rubygems_version: 1.3.
|
96
|
+
rubyforge_project: nowarning
|
97
|
+
rubygems_version: 1.3.7
|
96
98
|
signing_key:
|
97
99
|
specification_version: 3
|
98
100
|
summary: Classes for handling measurement units
|