phys-units 0.9.4 → 0.9.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f0ec7810800a733cda3aa7f753bf10d11b76891d
4
- data.tar.gz: b2c93b618d876183ea89ebfab9e6f353a6160746
3
+ metadata.gz: 08a3f10419f3f682ae605f4cc4995f0d99605354
4
+ data.tar.gz: d947bfc917e8484eeb87fc178f315b1e0982331c
5
5
  SHA512:
6
- metadata.gz: b0b1ea5529d3017813abe2c056b8eda47db00f47dd3cf0405fd0551182f551bdd95493352ea0ff8ecce1091e5269a593411c09d1caa705514d9c39520e8d54b5
7
- data.tar.gz: 7d4bdf5a200c37d8d9cd7b0416bbaa7812a988905b358ea93e88dd635f056226305a6c57bbae0bfe27c48ef7ed9080a64ca91a28fcabc9b66675b4ab082443fd
6
+ metadata.gz: ef99074dc223bb887a79162e0928181eda392b87a1fae825c8a09691aca17083417125a9dee1548058b917f41344742ac7366f3dd1cc867cb37bff3a9eab9d86
7
+ data.tar.gz: e8a23b4054cee7acfd274d274272ddda9cb2975efc316083030afffeb52c1debf1d86ec51b076231054d7bab85b17e813e9ce762dbb79ae055b91725c548ac10
data/README.md CHANGED
@@ -18,6 +18,10 @@ Or install from source tree:
18
18
 
19
19
  $ ruby setup.rb
20
20
 
21
+ Load Phys-Units library in your Ruby script:
22
+
23
+ require 'phys/units'
24
+
21
25
  ## Overview
22
26
 
23
27
  ### Phys::Quantity
@@ -25,15 +29,16 @@ is the primary class of Phys-Units library, intended to be manipulated by users.
25
29
  This class represents Physical Quantities with a Unit of measurement.
26
30
  It contains *Value* and *Unit*.
27
31
 
28
- * *Value*
29
- must be a class instance having arithmetic methods,
32
+ * *Value* of the quantity is given as the first parameter of
33
+ Quantity constructor (alias is `Quantity[]`).
34
+ It must be a class instance having arithmetic methods,
30
35
  but it is not necessary to be a Numeric.
31
36
  This is a duck typing way.
32
37
 
33
38
  Phys::Quantity[2.5,"miles"].value #=> 2.5
34
39
 
35
- * *Unit*
36
- is an instance of Phys::Unit class obtained by parsing *expr* string.
40
+ * *Unit* is an instance of Phys::Unit class.
41
+ It is created from the second argument of Quantity constructor.
37
42
 
38
43
  Phys::Quantity[2.5,"miles"].unit #=> #<Phys::Unit 1609.344,{"m"=>1},@expr="5280 ft">
39
44
 
@@ -62,7 +67,7 @@ It has *Factor* and *Dimension*:
62
67
  Q[123,'mile'] / Q[2,'hr'] #=> Phys::Quantity[61,'mile/hr']
63
68
  Q[61,'miles/hr'].want('m/s') #=> Phys::Quantity[27.26944,'m/s']
64
69
  Q[1.0,'are'] == Q[10,'m']**2 #=> true
65
- Q[70,'tempF'] + Q[10,'tempC'] #=> Phys::Quantity[88,'tempF']
70
+ Q[70,'tempF'] + Q[10,'degC'] #=> Phys::Quantity[88,'tempF']
66
71
  Q[20,'tempC'].want('tempF') #=> Phys::Quantity[68,'tempF']
67
72
  Math.cos(Q[60,'degree'].to_f) #=> 0.5
68
73
 
@@ -84,7 +89,7 @@ It has *Factor* and *Dimension*:
84
89
  Phys-Units library is differentiated from many other units libraries for Ruby,
85
90
  by the following features:
86
91
 
87
- * Compatible with GNU Units except nonlinear units.
92
+ * Compatible with GNU Units except currency and nonlinear units.
88
93
  * Provides 2331 units, 85 prefixes, including UTF-8 unit names.
89
94
  * Defines Units by reading GNU Units text data
90
95
  (see [load_units.rb](https://github.com/masa16/phys-units/blob/master/lib/phys/units/load_units.rb)),
@@ -127,6 +132,8 @@ Caution: The use of Mix-in may cause conflicts with other library.
127
132
  ## Platforms tested
128
133
 
129
134
  * ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-linux]
135
+ * ruby 1.9.3p392 (2013-02-22 revision 39386) [x86_64-linux]
136
+ * ruby 1.8.7 (2012-10-12 patchlevel 371) [x86_64-linux]
130
137
 
131
138
  ## Copying License
132
139
 
@@ -677,7 +677,7 @@ Racc_debug_parser = false
677
677
 
678
678
  module_eval(<<'.,.,', 'parse.y', 23)
679
679
  def _reduce_2(val, _values, result)
680
- result = Unit.inverse(val[1])
680
+ result = Unit.cast(val[1]).inverse
681
681
  result
682
682
  end
683
683
  .,.,
@@ -21,7 +21,7 @@ class Parse
21
21
  rule
22
22
 
23
23
  target: expr
24
- | DIV list { result = Unit.inverse(val[1]) }
24
+ | DIV list { result = Unit.cast(val[1]).inverse }
25
25
  ;
26
26
 
27
27
  expr: list
@@ -18,16 +18,17 @@ module Phys
18
18
  # intended to be manipulated by users.
19
19
  # This class represents Physical Quantities with a Unit of measurement.
20
20
  # It contains *Value* and *Unit*.
21
- # * *Value* of the quantity
22
- # must be an instance having arithmetic methods,
21
+ # * *Value* of the quantity is given as the first parameter of
22
+ # Quantity constructor (alias is +Quantity[]+).
23
+ # It must be a class instance having arithmetic methods,
23
24
  # but it is not necessary to be a Numeric.
24
25
  # This is a duck typing way.
25
26
  # Phys::Quantity[2.5,"miles"].value #=> 2.5
26
27
  # Phys::Quantity[NArray.float(5).indgen,"miles"].want("m").value
27
28
  # #=> NArray.float(5):
28
29
  # [ 0.0, 1609.34, 3218.69, 4828.03, 6437.38 ]
29
- # * *Unit*
30
- # is an instance of Phys::Unit class obtained by parsing *expr* string.
30
+ # * *Unit* is an instance of Phys::Unit class.
31
+ # It is created from the second argument of Quantity constructor.
31
32
  # see document of Phys::Unit.
32
33
  # Phys::Quantity[2.5,"miles"].unit #=> #<Phys::Unit 1609.344,{"m"=>1},@expr="5280 ft">
33
34
  #
@@ -39,7 +40,7 @@ module Phys
39
40
  # Q[123,'mile'] / Q[2,'hr'] #=> Phys::Quantity[61,'mile/hr']
40
41
  # Q[61,'miles/hr'].want('m/s') #=> Phys::Quantity[27.26944,'m/s']
41
42
  # Q[1.0,'are'] == Q[10,'m']**2 #=> true
42
- # Q[70,'tempF'] + Q[10,'tempC'] #=> Phys::Quantity[88,'tempF']
43
+ # Q[70,'tempF'] + Q[10,'degC'] #=> Phys::Quantity[88,'tempF']
43
44
  # Q[20,'tempC'].want('tempF') #=> Phys::Quantity[68,'tempF']
44
45
  # Math.cos(Q[60,'degree'].to_f) #=> 0.5
45
46
  #
@@ -51,31 +52,29 @@ module Phys
51
52
 
52
53
  class << self
53
54
  # Alias to Phys::Quantity.new.
54
- # @param [Object] value Value of quantity.
55
- # @param [String,Symbol] expr Unit string to be parsed later.
56
- # @overload initialize(value,unit)
57
- # @param [Object] value Value of quantity.
58
- # @param [Phys::Unit] unit This unit is copyed if exists.
59
- # @overload initialize(value)
60
- # @param [Object] value Value of dimensionless quantity.
55
+ # @param [Object] value Value of quantity.
56
+ # @param [String,Symbol,Phys::Unit] unit
57
+ # * If +unit+ String or Symbol, it is regarded as a unit expression (to be parsed later).
58
+ # * If +unit+ is Phys::Unit, it is used as the unit of new quantity.
59
+ # * If +unit+ is not provided, the quantity is regarded as dimensionless.
61
60
  # @return [Phys::Quantity]
62
61
  # @raise [TypeError] if invalid arg types.
63
62
  # @raise [Phys::UnitError] if unit conversion is failed.
64
- def [](value,expr=nil)
65
- self.new(value,expr)
63
+ def [](value,unit=nil)
64
+ self.new(value,unit)
66
65
  end
67
66
  end
68
67
 
69
68
  # Initialize a new quantity.
70
69
  # @overload initialize(value,expr,unit=nil)
71
70
  # @param [Object] value Value of quantity.
72
- # @param [String,Symbol] expr Unit string to be parsed later.
73
- # @param [Phys::Unit] unit This unit is copyed if exists.
71
+ # @param [String,Symbol] expr Unit expression.
72
+ # @param [Phys::Unit] unit If exists, this parameter is used as the unit of new quantity.
74
73
  # @overload initialize(value,unit)
75
74
  # @param [Object] value Value of quantity.
76
- # @param [Phys::Unit] unit This unit is copyed if exists.
75
+ # @param [Phys::Unit] unit This parameter is used as the unit of new quantity.
77
76
  # @overload initialize(value)
78
- # @param [Object] value Value of dimensionless quantity.
77
+ # @param [Object] value Value of a dimensionless quantity.
79
78
  # @raise [TypeError] if invalid arg types.
80
79
  # @raise [Phys::UnitError] if unit conversion is failed.
81
80
  #
@@ -291,8 +290,8 @@ module Phys
291
290
  @value > @unit.convert(other)
292
291
  end
293
292
 
294
- # Closeness. Returns +true+ if difference between +self+ and +other+ is
295
- # smaller than +epsilon+ times sum of their absolute values.
293
+ # Closeness. Returns +true+ if
294
+ # (self-other).abs <= (self.abs+other.abs) * epsilon
296
295
  # Before the comparison, it converts +other+ to the unit of +self+.
297
296
  # @param [Phys::Quantity] other
298
297
  # @param [Numeric] epsilon
@@ -301,7 +300,7 @@ module Phys
301
300
  def close_to(other,epsilon=Float::EPSILON)
302
301
  other_value = @unit.convert(other)
303
302
  abs_sum = @value.abs+other_value.abs
304
- abs_sum==0 || (@value-other_value).abs/abs_sum <= epsilon
303
+ (@value-other_value).abs <= abs_sum*epsilon
305
304
  end
306
305
 
307
306
  # Exponentiation.
@@ -365,6 +364,9 @@ module Phys
365
364
  # If the +other+ param is *not* Phys::Quantity,
366
365
  # +other+ is regarded as a dimensionless value.
367
366
  # The values and units are divided respectively.
367
+ # Note that the method of the value's class is used.
368
+ # @example
369
+ # Phys::Quantity[3,:m]/2 #=> Phys::Quantity[1,"m"]
368
370
  # @param [Object] other
369
371
  # @return [Phys::Quantity] a quantity
370
372
  # @raise [Phys::UnitError] if unit is not operable.
@@ -555,7 +557,7 @@ module Phys
555
557
  self.class.to_s+"["+Unit::Utils.num_inspect(@value)+expr+"]"+sufx
556
558
  end
557
559
 
558
- # Comformability of quantity. Returns true if unit conversion between +self+ and +x+ is possible.
560
+ # Conformability of quantity. Returns true if unit conversion between +self+ and +x+ is possible.
559
561
  # @param [Object] x other object (Unit or Quantity or Numeric or something else)
560
562
  # @return [Boolean]
561
563
  def ===(x)
@@ -43,12 +43,13 @@ module Phys
43
43
  #
44
44
  class Unit
45
45
 
46
- # @visibility private
46
+ # Hash table of registered units.
47
47
  LIST = {}
48
- # @visibility private
48
+ # Hash table of registered prefixes.
49
49
  PREFIX = {}
50
50
 
51
- # @visibility private
51
+ # Regex for registered prefixes.
52
+ # @return [Regexp]
52
53
  def self.prefix_regex
53
54
  @@prefix_regex
54
55
  end
@@ -58,11 +59,12 @@ module Phys
58
59
  # @param [Numeric] factor Unit scale factor.
59
60
  # @param [Hash] dimension Dimension hash.
60
61
  # @overload initialize(expr,name=nil)
61
- # @param [String] expr Unit string to be parsed later.
62
- # @param [String] name Name of this unit.
62
+ # @param [String] expr Expression of the unit. It is parsed lazily, i.e.,
63
+ # parsed not when this instance is created, but when @factor and @dim is used.
64
+ # @param [String] name Name of the unit.
63
65
  # @overload initialize(unit,name=nil)
64
- # @param [Phys::Unit] unit Copy contents from the argument.
65
- # @param [String] name Name of this unit.
66
+ # @param [Phys::Unit] unit Its contents is used for new unit.
67
+ # @param [String] name Name of the unit.
66
68
  # @raise [TypeError] if invalid arg types.
67
69
  #
68
70
  def initialize(a1,a2=nil)
@@ -83,7 +85,7 @@ module Phys
83
85
  end
84
86
  end
85
87
 
86
- # Unit expression to be parsed.
88
+ # Expression of the unit.
87
89
  # @return [String, NilClass]
88
90
  attr_reader :expr
89
91
 
@@ -199,6 +201,12 @@ module Phys
199
201
  end
200
202
  alias string_form unit_string
201
203
 
204
+ # Returns self name or unit_string
205
+ # @return [String]
206
+ def to_s
207
+ @name || unit_string
208
+ end
209
+
202
210
  # Conversion Factor to base unit, including dimension-value.
203
211
  # @return [Numeric]
204
212
  # @example
@@ -221,7 +229,7 @@ module Phys
221
229
  end
222
230
 
223
231
  # Returns true if scalar unit.
224
- # *Scalar* means the unit does not have any dimension
232
+ # *Scalar* means this unit does not have any dimension
225
233
  # including dimensionless-units, and its factor is one.
226
234
  # @return [Boolean]
227
235
  def scalar?
@@ -306,7 +314,13 @@ module Phys
306
314
  # @return [Phys::Quantity]
307
315
  # @raise [UnitError] if unit conversion is failed.
308
316
  def convert_scale(quantity)
309
- convert(quantity)
317
+ if Quantity===quantity
318
+ assert_same_dimension(quantity.unit)
319
+ v = quantity.value * quantity.unit.conversion_factor
320
+ v = v / self.conversion_factor
321
+ else
322
+ quantity / to_numeric
323
+ end
310
324
  end
311
325
 
312
326
  # Convert from a value in this unit to a value in base unit.
@@ -459,7 +473,7 @@ module Phys
459
473
  if scalar?
460
474
  return x
461
475
  elsif x.scalar?
462
- return self
476
+ return self.dup
463
477
  end
464
478
  check_operable2(x)
465
479
  dims = dimension_binop(x){|a,b| a+b}
@@ -477,7 +491,7 @@ module Phys
477
491
  if scalar?
478
492
  return x.inverse
479
493
  elsif x.scalar?
480
- return self
494
+ return self.dup
481
495
  end
482
496
  check_operable2(x)
483
497
  dims = dimension_binop(x){|a,b| a-b}
@@ -496,11 +510,6 @@ module Phys
496
510
  Unit.new(Rational(1,self.factor), dims)
497
511
  end
498
512
 
499
- # @visibility private
500
- def self.inverse(x)
501
- Unit.cast(x).inverse
502
- end
503
-
504
513
  # Exponentiation of units.
505
514
  # This units must be operable.
506
515
  # @param [Numeric] x numeric
@@ -515,8 +524,11 @@ module Phys
515
524
 
516
525
  # @visibility private
517
526
  def self.func(fn, x)
518
- fn = 'log' if fn == 'ln'
519
527
  m = Unit.new(x).to_numeric
528
+ if fn == 'log2' && RUBY_VERSION<'1.9.0'
529
+ return Unit.new( Math.log(m)/Math.log(2) )
530
+ end
531
+ fn = 'log' if fn == 'ln'
520
532
  Unit.new( Math.send(fn,m) )
521
533
  end
522
534
 
@@ -547,7 +559,7 @@ module Phys
547
559
 
548
560
  # BaseUnit is a class to represent units defined by "!"
549
561
  # in the data form of GNU units.
550
- # It includes SI units and dimensinless units such as radian.
562
+ # It includes SI units and dimensionless units such as radian.
551
563
  class BaseUnit < Unit
552
564
 
553
565
  def self.define(name,expr,dimval=nil)
@@ -601,7 +613,19 @@ module Phys
601
613
 
602
614
 
603
615
  # OffsetUnit is a class to represent units with offset value.
604
- # Allows Farenheight/Celsius temperature.
616
+ # Allows Fahrenheit/Celsius temperature.
617
+ # Unit operations are not allowed.
618
+ # @example
619
+ # require 'phys/units'
620
+ #
621
+ # Phys::Quantity[20,:tempC].want(:tempF) #=> Phys::Quantity[68,'tempF']
622
+ # Phys::Quantity[3,:tempC] + Phys::Quantity[10,:degF] #=> Phys::Quantity[(77/9),"tempC"]
623
+ # Phys::Quantity[3,:tempC] * Phys::Quantity[3,:m] #=> UnitError
624
+ # Phys::Quantity[3,:tempC] ** 2 #=> UnitError
625
+ #
626
+ # # Next examples currently work, but I suggest the use of degC and degF.
627
+ # Phys::Quantity[3,:tempC] + Phys::Quantity[10,:tempF] #=> Phys::Quantity[(77/9),"tempC"]
628
+ # Phys::Quantity[3,:tempC] * 2 #=> Phys::Quantity[6,"tempC"]
605
629
  class OffsetUnit < Unit
606
630
 
607
631
  def self.define(name,unit,offset=nil)
@@ -616,20 +640,6 @@ module Phys
616
640
  @offset = offset
617
641
  end
618
642
 
619
- # Convert a quantity to this unit only in scale.
620
- # @param [Phys::Quantity] quantity to be converted.
621
- # @return [Phys::Quantity]
622
- # @raise [UnitError] if unit conversion is failed.
623
- def convert_scale(quantity)
624
- if Quantity===quantity
625
- assert_same_dimension(quantity.unit)
626
- v = quantity.value * quantity.unit.conversion_factor
627
- v = v / self.conversion_factor
628
- else
629
- raise UnitError,"not Quantity: #{quantity.inspect}"
630
- end
631
- end
632
-
633
643
  # Convert from a value in this unit to a value in base unit.
634
644
  # @param [Numeric] value
635
645
  # @return [Numeric]
@@ -644,6 +654,7 @@ module Phys
644
654
  (value - @offset) / conversion_factor
645
655
  end
646
656
 
657
+ # Returns false
647
658
  def operable?
648
659
  false
649
660
  end
@@ -18,9 +18,11 @@ module Phys
18
18
  false
19
19
  end
20
20
 
21
- # Define a new Unit. Expression is not parsed at the time of this method.
22
- # @param [String,Symbol] name Name of this unit.
23
- # @param [String] expr Expression.
21
+ # Define a new Unit. Expression is parsed lazily, i.e., parsed
22
+ # not when this method is called, but when @factor and @dim is used.
23
+ # Note that the result of unit calculation depends on the timing of unit definition.
24
+ # @param [String,Symbol] name Name of the unit.
25
+ # @param [String] expr Expression of the unit.
24
26
  def define(name,expr)
25
27
  case name
26
28
  when String
@@ -49,8 +51,9 @@ module Phys
49
51
 
50
52
 
51
53
  # Force the argument to be Phys::Unit.
52
- # @param [Phys::Unit,Numeric]
54
+ # @param [Object] x
53
55
  # @return [Phys::Unit]
56
+ # @raise [TypeError] if invalid type for units.
54
57
  def cast(x)
55
58
  case x
56
59
  when Unit
@@ -14,6 +14,8 @@ module Phys
14
14
  # Defines method with unit name.
15
15
  # *Caution*: Variable names may conflict with unit names.
16
16
  # @example
17
+ # require 'phys/units'
18
+ #
17
19
  # Phys::UnitsMixin.module_eval do
18
20
  # puts 123.4*km
19
21
  # puts (23*mile/hr).want(m/s)
@@ -60,6 +62,8 @@ module Phys
60
62
  # ActiveSupport-like mix-in.
61
63
  # *Caution*: This kind of global change will cause unexpected problems.
62
64
  # @example
65
+ # require 'phys/units'
66
+ #
63
67
  # class Numeric
64
68
  # include Phys::UnitsNumericMixin
65
69
  # end
@@ -1,5 +1,5 @@
1
1
  module Phys
2
2
  class Unit
3
- VERSION = "0.9.4"
3
+ VERSION = "0.9.5"
4
4
  end
5
5
  end
data/lib/phys/units.rb CHANGED
@@ -1,3 +1,6 @@
1
+ if RUBY_VERSION<'1.9.0'
2
+ require "rational"
3
+ end
1
4
  require "phys/units/version"
2
5
  require "phys/units/errors.rb"
3
6
  require "phys/units/unit_class.rb"
@@ -0,0 +1,7 @@
1
+ # http://www.tokyo-dome.co.jp/dome/facilities/
2
+ tokyodome_area 46755 m^2
3
+ tokyodome_volume 1240000 m^3
4
+
5
+ # http://www.tokyo-skytree.jp/archive/spec/
6
+ skytree_height 634 m
7
+ skytree skytree_height
data/misc/mkunitspec.rb CHANGED
@@ -8,6 +8,7 @@ def close_values(a,b)
8
8
  end
9
9
 
10
10
  puts <<EOL
11
+ # -*- coding: utf-8 -*-
11
12
  $LOAD_PATH.unshift File.dirname(__FILE__)
12
13
  require "helper"
13
14
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  $LOAD_PATH.unshift File.dirname(__FILE__)
2
3
  require "helper"
3
4
 
@@ -126,10 +126,10 @@ describe "Phys::Quantity" do
126
126
  end
127
127
 
128
128
  context "Temperature" do
129
- describe Q[1,"tempC"] - Q[1,"tempC"] do
129
+ describe Q[1,"tempC"] - Q[1,"degC"] do
130
130
  it {should == Q[0,"tempC"]}
131
131
  end
132
- describe Q[50,"tempF"] + Q[10,"tempC"] do
132
+ describe Q[50,"tempF"] + Q[10,"degC"] do
133
133
  it {should == Q[68,"tempF"]}
134
134
  end
135
135
  describe Q[0,"tempC"].want("tempF") do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phys-units
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro TANAKA
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-05 00:00:00.000000000 Z
11
+ date: 2013-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -65,6 +65,7 @@ files:
65
65
  - lib/phys/units/units_mixin.rb
66
66
  - lib/phys/units/utils.rb
67
67
  - lib/phys/units/version.rb
68
+ - misc/misc_units.dat
68
69
  - misc/mkjpspec.rb
69
70
  - misc/mkunitspec.rb
70
71
  - misc/readme.jp.md