Parent

Van::Units::Unit

This class represents a Unit. A Unit uses a given Converter with a number of registered units in which it can be expressed. A Unit is the product of the powers of other units. In principle, these need not be integer powers, but this may cause problems with rounding. The following code for example returns false:

  Unit.new(:m => 0.1) * Unit.new(:m => 0.2) == Unit.new(:m => 0.3)

Units can be multiplied, divided, and raised to a given power. As an extra, 1 can be divided by a Unit.

Examples:

  Unit.new(:mi => 1, :s => -1) ** 2 # => mi**2/s**2
  Unit.new(:mi => 1, :s => -1) * Unit.new(:s => 1, :usd => -1) # => mi/usd
  Unit.new(:mi => 1, :s => -1, Converter.converter(:uk)) *
    Unit.new(:s => 1, :usd => -1, Converter.converter(:us)) # => TypeError
  1 / Unit.new(:mi => 1, :s => -1) # => s/mi

Attributes

units[R]

Public Class Methods

new(units = {}, converter = nil) click to toggle source

Creates a new (composite) Unit. It is passed a hash of the form {:unit => exponent}, and the Converter to use.

Examples:

  Unit.new(:m => 1, :s => -1, Converter.converter(:uk)) # => m/s
  Unit.new(:mi => 1, :s => -2) # => mi/s**2

See also Converter, Converter.converter

     # File lib/van/units/base.rb, line 206
206:     def initialize(units = {}, converter = nil)
207:       conv = proc { converter ||= Units::Converter.current }
208:       if units.is_a? ::String
209:         @units = decode_string(units, conv)
210:       else
211:         @units = {}
212:         units.each_pair do |k, v|
213:           k = conv[].base_unit(k.to_sym) if not k.is_a? Units::BaseUnit
214:           @units[k] = v
215:         end
216:       end
217:       normalize_units
218:     end

Public Instance Methods

*(other) click to toggle source

Multiplies with the given Unit.

     # File lib/van/units/base.rb, line 230
230:     def *(other)
231:       do_op(:*, :+, other)
232:     end
**(p) click to toggle source

Raises to the given power.

     # File lib/van/units/base.rb, line 221
221:     def **(p)
222:       result = {}
223:       @units.each_pair do |u, e|
224:         result[u] = e * p
225:       end
226:       Units::Unit.new(result)
227:     end
/(other) click to toggle source

Divides by the given Unit.

     # File lib/van/units/base.rb, line 235
235:     def /(other)
236:       do_op(:/, :-, other)
237:     end
==(other) click to toggle source

Returns true iff the two units are equals, i.e., iff they have the same exponent for all units, and they both use the same Converter.

     # File lib/van/units/base.rb, line 255
255:     def ==(other)
256:       other.is_a?(Units::Unit) && other.units == units
257:     end
Also aliased as: eql?
compatible_with?(other) click to toggle source

Returns true iff this Unit is compatible with the given Unit. This is less strict than equality because for example hours are compatible with seconds (“we can add them”), but hours are not seconds.

     # File lib/van/units/base.rb, line 268
268:     def compatible_with?(other)
269:       conv1, conv2 = Units::Converter.coerce_units(self, other)
270:       conv1.units == conv2.units
271:     end
eql?(other) click to toggle source
Alias for: ==
hash() click to toggle source
     # File lib/van/units/base.rb, line 261
261:     def hash
262:       @units.to_a.map { |e| e.hash }.hash
263:     end
inspect() click to toggle source
Alias for: to_s
method_missing(m, *args, &blk) click to toggle source
     # File lib/van/units/base.rb, line 291
291:     def method_missing(m, *args, &blk)
292:       if args.length == 1
293:         args[0] = (Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? Units::Converter
294:         return self * Units::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
295:       elsif (Units::Converter.current.registered?(m) rescue false)
296:         raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
297:         return self * Units::Unit.new({m => 1}, Units::Converter.current)
298:       end
299:       ::Exception.with_clean_backtrace("method_missing") {
300:         super
301:       }
302:     end
simplify() click to toggle source
     # File lib/van/units/base.rb, line 249
249:     def simplify
250:       Units::Converter.simplify_unit(self)
251:     end
to_s() click to toggle source

Returns a human readable string representation.

     # File lib/van/units/base.rb, line 274
274:     def to_s
275:       numerator = ""
276:       denominator = ""
277:       @units.each_pair do |u, e|
278:         e_abs = e > 0 ? e : -e # This works with Complex too
279:         (e > 0 ? numerator : denominator) << " #{u.to_s}#{"**#{e_abs}" if e_abs != 1}"
280:       end
281:       "#{numerator.lstrip}#{"/" + denominator.lstrip if not denominator.empty?}"
282:     end
Also aliased as: inspect
to_unit(converter = nil) click to toggle source

Returns self.

     # File lib/van/units/base.rb, line 285
285:     def to_unit(converter = nil)
286:       self
287:     end
unitless?() click to toggle source

Returns true iff this Unit has all exponents equal to 0.

     # File lib/van/units/base.rb, line 240
240:     def unitless?
241:       @units.empty?
242:     end

Private Instance Methods

decode_multiplicative_string(s, multiplier, converter, result) click to toggle source
     # File lib/van/units/base.rb, line 320
320:     def decode_multiplicative_string(s, multiplier, converter, result)
321:       s.scan(Units::Regexps::SINGLE_UNIT_REGEXP) do |conv, unit, exp|
322:         if unit
323:           conv = Units::Converter.converter(conv)
324:         else
325:           conv, unit = converter[], conv
326:         end
327:         exp ||= '1'
328:         unit = conv.base_unit(unit)
329:         result[unit] = (result[unit] || 0) + Integer(exp) * multiplier
330:       end
331:     end
decode_string(s, converter) click to toggle source
     # File lib/van/units/base.rb, line 306
306:     def decode_string(s, converter)
307:       if Units::Regexps::TOTAL_UNIT_REGEXP =~ s
308:         numerator, denominator = $1, $2
309:         units = {}
310:         decode_multiplicative_string(numerator, 1, converter, units) if numerator
311:         decode_multiplicative_string(denominator, 1, converter, units) if denominator
312:         units
313:       elsif /^\s*$/ =~ s
314:         {}
315:       else
316:         raise ::ArgumentError, "Illegal unit string #{s.dump}"
317:       end
318:     end
do_op(op, dual_op, other) click to toggle source
     # File lib/van/units/base.rb, line 339
339:     def do_op(op, dual_op, other)
340:       other = other.to_unit
341:       raise TypeError, "cannot convert to Unit" unless Units::Unit === other
342:       result = @units.dup
343:       other.units.each_pair do |u, e|
344:         result[u] = 0 if not result[u]
345:         result[u] = result[u].send(dual_op, e)
346:       end
347:       Units::Unit.new(result)
348:     end
normalize_units() click to toggle source
     # File lib/van/units/base.rb, line 333
333:     def normalize_units
334:       @units.keys.each do |unit|
335:         @units.delete(unit) if @units[unit] == 0
336:       end
337:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.