ruby-units 1.4.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -1,5 +1,9 @@
1
1
  Change Log for Ruby-units
2
2
  =========================
3
+ 2012-09-16 1.4.2 * Fix issue #54 -- pluralization of fluid-ounces
4
+ * Fix issue #53, 51 -- incorrect definition for gee
5
+ * Fix issue #52 -- add support for degree symbol
6
+ * Fix issue #50 -- fix conversion to json
3
7
  2012-05-13 1.4.1 * Fix issue #40 -- Unit parsing truncates invalid portions of the unit
4
8
  * Fix issue #41 -- initializing with a nil gives unexpected result
5
9
  2012-02-01 * Fix issue #34 -- Time.at takes more than one parameter
data/RakeFile CHANGED
@@ -57,7 +57,7 @@ begin
57
57
  desc "Run specs"
58
58
  RSpec::Core::RakeTask.new do |spec|
59
59
  puts
60
- puts %x{rvm current}
60
+ # puts %x{rvm current}
61
61
  puts
62
62
  end
63
63
 
@@ -88,4 +88,4 @@ end
88
88
  desc "Run specs against several ruby versions, requires rvm"
89
89
  task "spec:all" => rubies.keys.map {|name| "spec:#{name}"}
90
90
 
91
- task :default => :spec
91
+ task :default => :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.1
1
+ 1.4.2
@@ -21,7 +21,7 @@ end
21
21
  # in the United States. If your favorite units are not listed here, file an issue on github.
22
22
  #
23
23
  # To add or override a unit definition, add a code block like this..
24
- # @example Define a new unit
24
+ # @example Define a new unit
25
25
  # Unit.define("foobar") do |unit|
26
26
  # unit.aliases = %w{foo fb foo-bar}
27
27
  # unit.definition = Unit("1 baz")
@@ -59,8 +59,7 @@ class Unit < Numeric
59
59
  FAHRENHEIT = ['<fahrenheit>']
60
60
  RANKINE = ['<rankine>']
61
61
  CELSIUS = ['<celsius>']
62
- TEMP_REGEX = /(?:temp|deg)[CFRK]/
63
-
62
+ @@TEMP_REGEX = nil
64
63
  SIGNATURE_VECTOR = [
65
64
  :length,
66
65
  :time,
@@ -141,19 +140,19 @@ class Unit < Numeric
141
140
  @@definitions.each do |name, definition|
142
141
  self.use_definition(definition)
143
142
  end
144
-
143
+
145
144
  Unit.new(1)
146
145
  return true
147
146
  end
148
-
149
-
147
+
148
+
150
149
  # determine if a unit is already defined
151
150
  # @param [String] unit
152
151
  # @return [Boolean]
153
152
  def self.defined?(unit)
154
153
  return @@UNIT_VALUES.keys.include?("<#{unit}>")
155
154
  end
156
-
155
+
157
156
  # return the unit definition for a unit
158
157
  # @param [String] unit
159
158
  # @return [Unit::Definition, nil]
@@ -161,13 +160,13 @@ class Unit < Numeric
161
160
  unit = (_unit =~ /^<.+>$/) ? _unit : "<#{_unit}>"
162
161
  return @@definitions[unit]
163
162
  end
164
-
163
+
165
164
  # return a list of all defined units
166
165
  # @return [Array]
167
166
  def self.definitions
168
167
  return @@definitions
169
168
  end
170
-
169
+
171
170
  # @param [Unit::Definition|String] unit_definition
172
171
  # @param [Block] block
173
172
  # @return [Unit::Definition]
@@ -191,7 +190,7 @@ class Unit < Numeric
191
190
  Unit.use_definition(unit_definition)
192
191
  return unit_definition
193
192
  end
194
-
193
+
195
194
  # @param [String] name Name of unit to redefine
196
195
  # @param [Block] block
197
196
  # @raise [ArgumentError] if a block is not given
@@ -204,7 +203,7 @@ class Unit < Numeric
204
203
  yield unit_definition
205
204
  self.define(unit_definition)
206
205
  end
207
-
206
+
208
207
  # @param [String] name of unit to undefine
209
208
  # @return (see Unit.setup)
210
209
  # Undefine a unit. Will not raise an exception for unknown units.
@@ -212,12 +211,12 @@ class Unit < Numeric
212
211
  @@definitions.delete("<#{unit}>")
213
212
  Unit.setup
214
213
  end
215
-
214
+
216
215
  include Comparable
217
216
 
218
217
  # @return [Numeric]
219
218
  attr_accessor :scalar
220
-
219
+
221
220
  # @return [Array]
222
221
  attr_accessor :numerator
223
222
 
@@ -225,20 +224,20 @@ class Unit < Numeric
225
224
  attr_accessor :denominator
226
225
 
227
226
  # @return [Integer]
228
- attr_accessor :signature
227
+ attr_accessor :signature
229
228
 
230
229
  # @return [Numeric]
231
230
  attr_accessor :base_scalar
232
-
231
+
233
232
  # @return [Array]
234
233
  attr_accessor :base_numerator
235
-
234
+
236
235
  # @return [Array]
237
236
  attr_accessor :base_denominator
238
-
237
+
239
238
  # @return [String]
240
239
  attr_accessor :output
241
-
240
+
242
241
  # @return [String]
243
242
  attr_accessor :unit_name
244
243
 
@@ -265,7 +264,7 @@ class Unit < Numeric
265
264
 
266
265
  if RUBY_VERSION < "1.9"
267
266
  # :nocov_19:
268
-
267
+
269
268
  # a list of properties to emit to yaml
270
269
  # @return [Array]
271
270
  def to_yaml_properties
@@ -370,11 +369,11 @@ class Unit < Numeric
370
369
  unary_unit = self.units || ""
371
370
  if options.first.instance_of?(String)
372
371
  opt_scalar, opt_units = Unit.parse_into_numbers_and_units(options[0])
373
- unless @@cached_units.keys.include?(opt_units) || (opt_units =~ /(#{TEMP_REGEX})|(pounds|lbs[ ,]\d+ ounces|oz)|('\d+")|(ft|feet[ ,]\d+ in|inch|inches)|%|(#{TIME_REGEX})|i\s?(.+)?|&plusmn;|\+\/-/)
372
+ unless @@cached_units.keys.include?(opt_units) || (opt_units =~ /(#{Unit.temp_regex})|(pounds|lbs[ ,]\d+ ounces|oz)|('\d+")|(ft|feet[ ,]\d+ in|inch|inches)|%|(#{TIME_REGEX})|i\s?(.+)?|&plusmn;|\+\/-/)
374
373
  @@cached_units[opt_units] = (self.scalar == 1 ? self : opt_units.unit) if opt_units && !opt_units.empty?
375
374
  end
376
375
  end
377
- unless @@cached_units.keys.include?(unary_unit) || (unary_unit =~ /#{TEMP_REGEX}/) then
376
+ unless @@cached_units.keys.include?(unary_unit) || (unary_unit =~ /#{Unit.temp_regex}/) then
378
377
  @@cached_units[unary_unit] = (self.scalar == 1 ? self : unary_unit.unit)
379
378
  end
380
379
  [@scalar, @numerator, @denominator, @base_scalar, @signature, @is_base].each {|x| x.freeze}
@@ -441,7 +440,7 @@ class Unit < Numeric
441
440
  # @todo this is brittle as it depends on the display_name of a unit, which can be changed
442
441
  def to_base
443
442
  return self if self.is_base?
444
- if self.units =~ /\A(?:temp|deg)[CRF]\Z/
443
+ if @@UNIT_MAP[self.units] =~ /\A<(?:temp|deg)[CRF]>\Z/
445
444
  if RUBY_VERSION < "1.9"
446
445
  # :nocov_19:
447
446
  @signature = @@KINDS.index(:temperature)
@@ -563,7 +562,7 @@ class Unit < Numeric
563
562
  # @return [Boolean]
564
563
  # @todo use unit definition to determine if it's a temperature instead of a regex
565
564
  def is_temperature?
566
- return self.is_degree? && (!(self.units =~ /temp[CFRK]/).nil?)
565
+ return self.is_degree? && (!(@@UNIT_MAP[self.units] =~ /temp[CFRK]/).nil?)
567
566
  end
568
567
  alias :temperature? :is_temperature?
569
568
 
@@ -579,7 +578,7 @@ class Unit < Numeric
579
578
  # @return [String] possible values: degC, degF, degR, or degK
580
579
  def temperature_scale
581
580
  return nil unless self.is_temperature?
582
- return "deg#{self.units[/temp([CFRK])/,1]}"
581
+ return "deg#{@@UNIT_MAP[self.units][/temp([CFRK])/,1]}"
583
582
  end
584
583
 
585
584
  # returns true if no associated units
@@ -946,25 +945,25 @@ class Unit < Numeric
946
945
  start_unit = self.units
947
946
  target_unit = other.units rescue other
948
947
  unless @base_scalar
949
- @base_scalar = case start_unit
950
- when 'tempC'
948
+ @base_scalar = case @@UNIT_MAP[start_unit]
949
+ when '<tempC>'
951
950
  @scalar + 273.15
952
- when 'tempK'
951
+ when '<tempK>'
953
952
  @scalar
954
- when 'tempF'
953
+ when '<tempF>'
955
954
  (@scalar+459.67)*Rational(5,9)
956
- when 'tempR'
955
+ when '<tempR>'
957
956
  @scalar*Rational(5,9)
958
957
  end
959
958
  end
960
- q= case target_unit
961
- when 'tempC'
959
+ q= case @@UNIT_MAP[target_unit]
960
+ when '<tempC>'
962
961
  @base_scalar - 273.15
963
- when 'tempK'
962
+ when '<tempK>'
964
963
  @base_scalar
965
- when 'tempF'
964
+ when '<tempF>'
966
965
  @base_scalar * Rational(9,5) - 459.67
967
- when 'tempR'
966
+ when '<tempR>'
968
967
  @base_scalar * Rational(9,5)
969
968
  end
970
969
  return Unit.new("#{q} #{target_unit}")
@@ -1025,6 +1024,12 @@ class Unit < Numeric
1025
1024
  raise RuntimeError, "Cannot convert '#{self.to_s}' to Rational unless unitless. Use Unit#scalar"
1026
1025
  end
1027
1026
 
1027
+ # Returns string formatted for json
1028
+ # @return [String]
1029
+ def as_json(*args)
1030
+ to_s
1031
+ end
1032
+
1028
1033
  # returns the 'unit' part of the Unit object without the scalar
1029
1034
  # @return [String]
1030
1035
  def units
@@ -1034,7 +1039,7 @@ class Unit < Numeric
1034
1039
  output_denominator = []
1035
1040
  num = @numerator.clone.compact
1036
1041
  den = @denominator.clone.compact
1037
-
1042
+
1038
1043
  if @numerator == UNITY_ARRAY
1039
1044
  output_numerator << "1"
1040
1045
  else
@@ -1042,11 +1047,11 @@ class Unit < Numeric
1042
1047
  if defn && defn.prefix?
1043
1048
  output_numerator << defn.display_name + Unit.definition(num.shift).display_name
1044
1049
  else
1045
- output_numerator << defn.display_name
1050
+ output_numerator << defn.display_name
1046
1051
  end
1047
1052
  end
1048
1053
  end
1049
-
1054
+
1050
1055
  if @denominator == UNITY_ARRAY
1051
1056
  output_denominator = []
1052
1057
  else
@@ -1054,11 +1059,11 @@ class Unit < Numeric
1054
1059
  if defn && defn.prefix?
1055
1060
  output_denominator << defn.display_name + Unit.definition(den.shift).display_name
1056
1061
  else
1057
- output_denominator << defn.display_name
1062
+ output_denominator << defn.display_name
1058
1063
  end
1059
1064
  end
1060
1065
  end
1061
-
1066
+
1062
1067
  on = output_numerator.uniq.
1063
1068
  map {|x| [x, output_numerator.count(x)]}.
1064
1069
  map {|element, power| ("#{element}".strip + (power > 1 ? "^#{power}" : ''))}
@@ -1098,9 +1103,9 @@ class Unit < Numeric
1098
1103
  end
1099
1104
 
1100
1105
  # @return [Numeric,Unit]
1101
- def round
1102
- return @scalar.round if self.unitless?
1103
- return Unit.new(@scalar.round, @numerator, @denominator)
1106
+ def round(ndigits = 0)
1107
+ return @scalar.round(ndigits) if self.unitless?
1108
+ return Unit.new(@scalar.round(ndigits), @numerator, @denominator)
1104
1109
  end
1105
1110
 
1106
1111
  # @return [Numeric, Unit]
@@ -1362,6 +1367,9 @@ class Unit < Numeric
1362
1367
  if unit_string =~ /\$\s*(#{NUMBER_REGEX})/
1363
1368
  unit_string = "#{$1} USD"
1364
1369
  end
1370
+
1371
+ unit_string.gsub!("\xC2\xB0".force_encoding('utf-8'), 'deg') unless RUBY_VERSION < '1.9'
1372
+
1365
1373
  unit_string.gsub!(/%/,'percent')
1366
1374
  unit_string.gsub!(/'/,'feet')
1367
1375
  unit_string.gsub!(/"/,'inch')
@@ -1474,7 +1482,7 @@ class Unit < Numeric
1474
1482
  @denominator = UNITY_ARRAY if @denominator.empty?
1475
1483
  return self
1476
1484
  end
1477
-
1485
+
1478
1486
  # return an array of base units
1479
1487
  # @return [Array]
1480
1488
  def self.base_units
@@ -1496,7 +1504,7 @@ class Unit < Numeric
1496
1504
  complex = %r{#{sci}{2,2}i}
1497
1505
  anynumber = %r{(?:(#{complex}|#{rational}|#{sci})\b)?\s?([\D].*)?}
1498
1506
  num, unit = string.scan(anynumber).first
1499
-
1507
+
1500
1508
  return [case num
1501
1509
  when NilClass
1502
1510
  1
@@ -1514,7 +1522,7 @@ class Unit < Numeric
1514
1522
  num.to_f
1515
1523
  end, unit.to_s.strip]
1516
1524
  end
1517
-
1525
+
1518
1526
  # return a fragment of a regex to be used for matching units or reconstruct it if hasn't been used yet.
1519
1527
  # Unit names are reverse sorted by length so the regexp matcher will prefer longer and more specific names
1520
1528
  # @return [String]
@@ -1522,7 +1530,7 @@ class Unit < Numeric
1522
1530
  def self.unit_regex
1523
1531
  @@UNIT_REGEX ||= @@UNIT_MAP.keys.sort_by {|unit_name| [unit_name.length, unit_name]}.reverse.join('|')
1524
1532
  end
1525
-
1533
+
1526
1534
  # return a regex used to match units
1527
1535
  # @return [RegExp]
1528
1536
  # @private
@@ -1536,11 +1544,21 @@ class Unit < Numeric
1536
1544
  def self.prefix_regex
1537
1545
  return @@PREFIX_REGEX ||= @@PREFIX_MAP.keys.sort_by {|prefix| [prefix.length, prefix]}.reverse.join('|')
1538
1546
  end
1539
-
1547
+
1548
+ def self.temp_regex
1549
+ @@TEMP_REGEX ||= Regexp.new "(?:#{
1550
+ temp_units=%w(tempK tempC tempF tempR degK degC degF degR)
1551
+ aliases=temp_units.map{|unit| d=Unit.definition(unit); d && d.aliases}.flatten.compact
1552
+ regex_str= aliases.empty? ? '(?!x)x' : aliases.join('|')
1553
+ regex_str
1554
+ })"
1555
+ end
1556
+
1540
1557
  # inject a definition into the internal array and set it up for use
1541
1558
  # @private
1542
1559
  def self.use_definition(definition)
1543
1560
  @@UNIT_MATCH_REGEX = nil #invalidate the unit match regex
1561
+ @@TEMP_REGEX = nil #invalidate the temp regex
1544
1562
  if definition.prefix?
1545
1563
  @@PREFIX_VALUES[definition.name] = definition.scalar
1546
1564
  definition.aliases.each {|_alias| @@PREFIX_MAP[_alias] = definition.name }
@@ -237,7 +237,7 @@ end
237
237
 
238
238
  Unit.define('fluid-ounce') do |floz|
239
239
  floz.definition = Unit('1/128 gal')
240
- floz.aliases = %w{floz fluid-ounce}
240
+ floz.aliases = %w{floz fluid-ounce fluid-ounces}
241
241
  end
242
242
 
243
243
  Unit.define('tablespoon') do |tbsp|
@@ -278,7 +278,7 @@ end
278
278
 
279
279
  Unit.define('gee') do |gee|
280
280
  # approximated as a rational number to minimize round-off errors
281
- gee.definition = Unit(Rational(196131,20000), 'm/s^2') # equivalent to 9.80655 m/s^2
281
+ gee.definition = Unit(Rational(196133,20000), 'm/s^2') # equivalent to 9.80665 m/s^2
282
282
  gee.aliases = %w{gee standard-gravitation}
283
283
  end
284
284
 
@@ -702,4 +702,4 @@ end
702
702
 
703
703
  Unit.define('ppb') do |ppb|
704
704
  ppb.definition = Unit(1) / 1_000_000_000
705
- end
705
+ end
data/ruby-units.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "ruby-units"
8
- s.version = "1.4.1"
8
+ s.version = "1.4.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Kevin Olbrich, Ph.D."]
12
- s.date = "2012-05-13"
12
+ s.date = "2012-09-16"
13
13
  s.description = "Provides classes and methods to perform unit math and conversions"
14
14
  s.email = ["kevin.olbrich+ruby_units@gmail.com"]
15
15
  s.extra_rdoc_files = [
@@ -62,8 +62,6 @@ Gem::Specification.new do |s|
62
62
  s.add_development_dependency(%q<jeweler>, [">= 0"])
63
63
  s.add_development_dependency(%q<rspec>, ["~> 2.5"])
64
64
  s.add_development_dependency(%q<autotest>, [">= 0"])
65
- s.add_development_dependency(%q<autotest-growl>, [">= 0"])
66
- s.add_development_dependency(%q<autotest-fsevent>, [">= 0"])
67
65
  else
68
66
  s.add_dependency(%q<bundler>, ["~> 1.0"])
69
67
  s.add_dependency(%q<rcov>, [">= 0"])
@@ -72,8 +70,6 @@ Gem::Specification.new do |s|
72
70
  s.add_dependency(%q<jeweler>, [">= 0"])
73
71
  s.add_dependency(%q<rspec>, ["~> 2.5"])
74
72
  s.add_dependency(%q<autotest>, [">= 0"])
75
- s.add_dependency(%q<autotest-growl>, [">= 0"])
76
- s.add_dependency(%q<autotest-fsevent>, [">= 0"])
77
73
  end
78
74
  else
79
75
  s.add_dependency(%q<bundler>, ["~> 1.0"])
@@ -83,8 +79,6 @@ Gem::Specification.new do |s|
83
79
  s.add_dependency(%q<jeweler>, [">= 0"])
84
80
  s.add_dependency(%q<rspec>, ["~> 2.5"])
85
81
  s.add_dependency(%q<autotest>, [">= 0"])
86
- s.add_dependency(%q<autotest-growl>, [">= 0"])
87
- s.add_dependency(%q<autotest-fsevent>, [">= 0"])
88
82
  end
89
83
  end
90
84
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-units
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-13 00:00:00.000000000 Z
12
+ date: 2012-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -123,38 +123,6 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: autotest-growl
128
- requirement: !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ! '>='
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ! '>='
140
- - !ruby/object:Gem::Version
141
- version: '0'
142
- - !ruby/object:Gem::Dependency
143
- name: autotest-fsevent
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ! '>='
148
- - !ruby/object:Gem::Version
149
- version: '0'
150
- type: :development
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
- requirements:
155
- - - ! '>='
156
- - !ruby/object:Gem::Version
157
- version: '0'
158
126
  description: Provides classes and methods to perform unit math and conversions
159
127
  email:
160
128
  - kevin.olbrich+ruby_units@gmail.com
@@ -240,6 +208,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
240
208
  - - ! '>='
241
209
  - !ruby/object:Gem::Version
242
210
  version: '0'
211
+ segments:
212
+ - 0
213
+ hash: -3013548990298419513
243
214
  required_rubygems_version: !ruby/object:Gem::Requirement
244
215
  none: false
245
216
  requirements: