This class represents a Value with a numeric value and a Unit. The numeric value can be any Numeric, though it is not recommended to use Values.
A Value can be added to, subtracted from and multiplied with another value, though only when both Values are using the same Converter. While multiplication is always possible, adding or subtracting values with incompatible units results in a TypeError. When two units are compatible but not the same, the Value with the larger of the units is converted to the smaller of the units. For example adding 100 seconds and 1 minute, the latter is converted to 60 seconds because a second is smaller than a minute. The result is 160 seconds.
Creates a new Value with the given numeric value and the given unit. Simply returns the given value if the given unit is unitless, i.e., when unit.unitless? is true.
# File lib/van/units/base.rb, line 381 381: def new(value, *args) 382: res = new!(value, *args) 383: return res.value if res.unit.unitless? 384: res 385: end
# File lib/van/units/base.rb, line 387 387: def new!(value, *args) 388: if ::String === value 389: str = *args 390: converter = case args.length 391: when 0 392: when 1 393: conv = args[0] 394: else 395: raise ArgumentError, "wrong number of arguments" 396: end 397: value, unit = decode_string(value, converter) 398: else 399: if args.length == 1 400: unit = args[0] 401: else 402: raise ArgumentError, "wrong number of arguments" 403: end 404: end 405: unit = Unit.new(unit) unless unit.is_a?(Unit) 406: old_new(value, unit) 407: end
# File lib/van/units/base.rb, line 577 577: def self.decode_string(s, converter) 578: if m = Units::Regexps::VALUE_REGEXP.match(s) 579: value = m[2].empty? ? Integer(m[1]) : Float(m[1]) 580: unit = Units::Unit.new(m[3], converter) 581: [value, unit] 582: else 583: raise ::ArgumentError, "Illegal value string #{s.dump}" 584: end 585: end
# File lib/van/units/base.rb, line 436 436: def div(other) 437: do_additive_op(:div, other)[0] 438: end
# File lib/van/units/base.rb, line 431 431: def divmod(other) 432: (q, r), unit = *do_additive_op(:divmod, other) 433: [q, Units::Value.new(r, unit)] 434: end
# File lib/van/units/base.rb, line 464 464: def hash 465: @value.hash ^ @unit.hash 466: end
# File lib/van/units/base.rb, line 562 562: def method_missing(m, *args, &blk) 563: if args.length == 1 564: args[0] = (Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? Units::Converter 565: return self * Units::Value.new(1, Units::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m) 566: elsif (Units::Converter.current.registered?(m) rescue false) 567: raise ::ArgumentError, "Wrong number of arguments" if args.length != 0 568: return self * Units::Value.new(1, Units::Unit.new({m => 1}, Units::Converter.current)) 569: end 570: ::Exception.with_clean_backtrace("method_missing") { 571: super 572: } 573: end
Converts this Value to the given Unit. This only works if the Converters used by this Value’s Unit and the given Unit are the same. It obviously fails if the Units are not compatible (can’t add apples and oranges).
# File lib/van/units/base.rb, line 488 488: def to(to_unit, converter = nil) 489: raise ArgumentError, "Wrong number of arguments" if converter && !(::String === to_unit) 490: to_unit = to_unit.to_unit(converter) 491: raise TypeError, "cannot convert to Unit" unless Units::Unit === to_unit 492: conv1, conv2 = unit.coerce(to_unit) 493: raise TypeError, "incompatible units for operation" if conv1.units != conv2.units 494: mult = conv1.multiplier / conv2.multiplier 495: Units::Value.new(value * mult, to_unit) 496: end
Returns a float if this Value is unitless, and raises an exception otherwise.
# File lib/van/units/base.rb, line 513 513: def to_f 514: val = simplify 515: if Units::Value === val 516: raise TypeError, "Cannot convert to float" 517: else 518: val.to_f 519: end 520: end
Returns an int if this Value is unitless, and raises an exception otherwise.
# File lib/van/units/base.rb, line 524 524: def to_i 525: val = simplify 526: if Units::Value === val 527: raise TypeError, "Cannot convert to integer" 528: else 529: val.to_i 530: end 531: end
Returns an int if this Value is unitless, and raises an exception otherwise.
# File lib/van/units/base.rb, line 535 535: def to_int 536: val = simplify 537: if Units::Value === val 538: raise TypeError, "Cannot convert to integer" 539: else 540: val.to_int 541: end 542: end
Returns a human readable string representation.
# File lib/van/units/base.rb, line 507 507: def to_s 508: "#{@value} #{@unit}" 509: end
# File lib/van/units/base.rb, line 587 587: def do_additive_op(op, other) 588: other = other.to_value 589: raise TypeError, "cannot convert to Value" unless Units::Value === other 590: if other.is_a? Units::Value 591: conv1, conv2 = unit.coerce(other.unit) 592: raise TypeError, "incompatible units for #{op}" if conv1.units != conv2.units 593: mult = conv2.multiplier / conv1.multiplier 594: if mult > 1 595: [value.send(op, other.value * mult), unit] 596: else 597: mult = conv1.multiplier / conv2.multiplier 598: [(value * mult).send(op, other.value), other.unit] 599: end 600: else 601: raise TypeError, "incompatible operands for #{op}" 602: end 603: end
# File lib/van/units/base.rb, line 605 605: def do_multiplicative_op(op, other) 606: case other 607: when Units::Value 608: [value.send(op, other.value), unit.send(op, other.unit)] 609: when Units::Unit 610: [value, unit.send(op, other)] 611: when ::Numeric 612: [value.send(op, other), unit] 613: else 614: # TODO: How to make this work for Units as well? 615: # Problem : how check whether to_value failed without 616: # masking all exceptions? 617: other = other.to_value 618: raise TypeError, "cannot convert to Value" unless Units::Value === other 619: do_multiplicative_op(op, other) 620: end 621: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.