sy 2.1.2 → 2.1.4

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: ae8923105001742a2064fd481c4d717be266bb0b
4
- data.tar.gz: 17eb6ed00ef92bb3198b924ac1bb26c78e65e43a
3
+ metadata.gz: 05a4502f974a88c613b402394d0e303bac458836
4
+ data.tar.gz: 799053c77aef863d27d6d5e816289a26fe48952d
5
5
  SHA512:
6
- metadata.gz: 260fb7cf5817e8a6f2e6580ed4ad4659907e0ef4c7afb359cb2c2bd3be491f42d0b5db086562d2306139906a7c09e7f004ee5a26ea6213a18d2b5afa77ef69a9
7
- data.tar.gz: 90c477a51032265b20e2b4b83d20278ccaa2e1dabca76fab66892226aac7afa646dbd351fa3003ccdb2e28c03f4837d8c6d3d2fa2594e6441aab7b3e8de5a15d
6
+ metadata.gz: 9d83e13e2eac8a780dce7ea70f9f578586bbf749e9d1aec39345b9a6d5f0b4dc24754ce0cfd81671cddef6016cc6a242a1885e3b0be09f827cd410139c6a6d8d
7
+ data.tar.gz: 90f1266a32befff128873f820ebc679ff97de0a5f3325724864f3b24b7e4c9d32b8b50d362a256419a886f5ab61f9ac8bf0af087d2915422b6f5aa9b956e6bb5
data/lib/sy.rb CHANGED
@@ -5,7 +5,6 @@ require 'y_support/name_magic'
5
5
  require 'y_support/core_ext/hash'
6
6
  require 'y_support/typing'
7
7
  require 'y_support/unicode'
8
- require 'y_support/abstract_algebra'
9
8
 
10
9
  require 'active_support/core_ext/module/delegation'
11
10
  require 'active_support/core_ext/array/extract_options'
@@ -71,10 +70,7 @@ module SY
71
70
  # of the constant "UNIT" implies, via YSupport's NameMagic mixin, that the
72
71
  # name of the object becomes :unit and that it is possible to use syntax
73
72
  # such as 42.unit to create magnitudes of SY::Amount.
74
- puts "About to construct UNIT." if SY::DEBUG
75
73
  UNIT = Unit.standard of: Amount
76
- puts "UNIT constructed. SY::Unit instances are " +
77
- "#{SY::Unit.instance_names}" if SY::DEBUG
78
74
 
79
75
  # AVOGADRO_CONSTANT (Nᴀ) is a certain well-known amount of things:
80
76
  Nᴀ = AVOGADRO_CONSTANT = 6.02214e23
@@ -83,11 +79,7 @@ module SY
83
79
  MoleAmount = Quantity.dimensionless coerces: Amount
84
80
 
85
81
  # And let SY::MOLE be its standard unit, related to SY::Amount via Nᴀ:
86
- puts "About to construct MOLE." if SY::DEBUG
87
82
  MOLE = Unit.standard of: MoleAmount, short: "mol", amount: Nᴀ * UNIT
88
- puts SY::Unit.__instances__ if SY::DEBUG
89
- puts "MOLE constructed. SY::Unit instances are" +
90
- "#{SY::Unit.instance_names}" if SY::DEBUG
91
83
 
92
84
  # === Basic dimension L (length)
93
85
 
@@ -185,7 +177,7 @@ module SY
185
177
  super
186
178
  end
187
179
 
188
- # FIXME: #% method etc
180
+ # TODO: #% method etc
189
181
  end
190
182
 
191
183
  # Making sure that for Celsius temperature, #°C returns absolute magnitude.
@@ -196,10 +188,6 @@ module SY
196
188
  end
197
189
  end
198
190
 
199
- # FIXME: Make this more systematic.
200
- # FIXME: Make sure that SI prefixes may not be used with Celsius
201
- # FIXME: Make sure that highly unusual SI prefixes may not be used
202
-
203
191
  class << CelsiusTemperature.send( :Magnitude )
204
192
  include SY::CelsiusMagnitude
205
193
  end
@@ -208,32 +196,9 @@ module SY
208
196
  include SY::CelsiusMagnitude
209
197
  end
210
198
 
211
- # alias :°C :celsius # with U+00B0 DEGREE SIGN
212
- # alias :˚C :celsius # with U+02DA RING ABOVE
213
- # alias :℃ :celsius # U+2103 DEGREE CELSIUS
214
-
215
- # FahrenheitTemperature = Quantity.of :Θ
216
- # FAHRENHEIT = Unit.standard of: FahrenheitTemperature, short: '°F'
217
- # # alias :°F :fahrenheit # with U+00B0 DEGREE SIGN
218
- # # alias :˚F :fahrenheit # with U+02DA RING ABOVE
219
- # # alias :℉ :fahrenheit # U+2109 DEGREE FAHRENHEIT
220
- # # FIXME: Patch FahrenheitTemperature to make it work with SY::Temperature
221
-
222
-
223
- # HUMAN_BODY_TEMPERATURE = 37.°C.( KELVIN )
224
- # STANDARD_TEMPERATURE = 25.°C.( KELVIN )
225
199
  HUMAN_BODY_TEMPERATURE = TP_H₂O + 37 * KELVIN
226
200
  STANDARD_LABORATORY_TEMPERATURE = TP_H₂O + 25 * KELVIN
227
201
 
228
- # === Dimensionless quantities
229
-
230
- # For now, these are just unimplemented proposals of what users might expect
231
- # from SY:
232
- #
233
- # degree, alias deg, ° # angle measure
234
- # arcminute, alias ʹ, ′ # angle measure
235
- # arcsecond, alias ʹʹ, ′′, ″
236
-
237
202
  # === Quantities of composite dimensions
238
203
 
239
204
  # Quantity SY::Area is obtained by raising quantity SY::Length to 2:
@@ -281,7 +246,7 @@ module SY
281
246
  # of its dimension.
282
247
  Speed = ( Length / Time ).standard!
283
248
 
284
- # Common constant
249
+ # Commonly used constant.
285
250
  SPEED_OF_LIGHT = 299_792_458 * METRE / SECOND
286
251
 
287
252
  # Supplementary unit of length.
@@ -299,7 +264,7 @@ module SY
299
264
  # For SY::Energy...
300
265
  Energy = ( Force * Length ).standard!
301
266
 
302
- # make SY::JOULE its standard unit:
267
+ # Make SY::JOULE its standard unit:
303
268
  JOULE = Unit.standard of: Energy, short: "J"
304
269
  # SY::CALORIE means thermochemical calorie:
305
270
  CALORIE = Unit.of Energy, short: "cal", amount: 4.184 * JOULE
@@ -331,11 +296,6 @@ module SY
331
296
  # make SY::VOLT its standard unit:
332
297
  VOLT = Unit.standard of: ElectricPotential, short: "V"
333
298
 
334
- # TODO: This should raise a friendly error:
335
- # MOLAR = Unit.standard of: Molarity, short: "M", amount: 1.mol.l⁻¹
336
- # (normal way of definition is MOLAR = Unit.standard of: Molarity, short: "M"
337
- # and it has already been defined to boot)
338
-
339
299
  # SY::Molality...
340
300
  Molality = MoleAmount / Mass
341
301
 
@@ -351,4 +311,4 @@ module SY
351
311
  ELEMENTARY_CHARGE = 1.60217656535e-19 * COULOMB
352
312
 
353
313
  ELECTRONVOLT = Unit.of Energy, short: "eV", amount: ELEMENTARY_CHARGE * VOLT
354
- end
314
+ end
@@ -18,24 +18,15 @@ module SY::AbsoluteMagnitude
18
18
  # and :amount named argument, where amount must be nonnegative.
19
19
  #
20
20
  def initialize( of: nil, amount: nil )
21
- puts "Constructing AbsoluteMagnitude of #{of}, amount: #{amount}" if SY::DEBUG
22
21
  fail ArgumentError, "Quantity (:of) argument missing!" if of.nil?
23
22
  @quantity = of
24
23
  @amount = case amount
25
- when Numeric then
26
- puts "This amount is a Numeric, using it directly" if SY::DEBUG
27
- amount
28
- when nil then
29
- puts "This amount is 'nil', using 1 instead" if SY::DEBUG
30
- 1
24
+ when Numeric then amount
25
+ when nil then 1
31
26
  else
32
27
  begin
33
- puts "Amount #{amount} will be reframed to #{@quantity}" if SY::DEBUG
34
28
  amount.( @quantity ).amount
35
- rescue NameError, NoMethodError
36
- puts "fail, amount #{amount} will be used directly" if SY::DEBUG
37
- amount
38
- end
29
+ rescue NameError, NoMethodError; amount end
39
30
  end
40
31
  fail SY::MagnitudeError, "Attempt to construct an unsigned magnitude " +
41
32
  "(SY::AbsoluteMagnitude) with a negative amount." if @amount < 0
@@ -44,16 +35,12 @@ module SY::AbsoluteMagnitude
44
35
  # For absolute magnitudes, #+ method always returns a result framed in
45
36
  # corresponding relative quantity.
46
37
  #
47
- # TODO: Figure out which module comes on the top in Quantity@Magnitude, whether Magnitude
48
- # or SignedMagnitude, and therefore, whether it is necessary to adjust this method.
49
38
  def + m2
50
39
  return magnitude amount + m2.amount if m2.quantity == quantity.relative
51
40
  return quantity.relative.magnitude( amount + m2.amount ) if
52
41
  quantity == m2.quantity
53
42
  return self if m2.equal? SY::ZERO
54
- # o1, o2 = m2.coerce( self )
55
- # return o1 + o2
56
- raise SY::QuantityError, "Unable to perform #{quantity} + #{m2.quantity}!"
43
+ fail SY::QuantityError, "Unable to perform #{quantity} + #{m2.quantity}!"
57
44
  end
58
45
 
59
46
  # Addition of absolute magnitudes that returns a result framed as
@@ -62,24 +49,18 @@ module SY::AbsoluteMagnitude
62
49
  def add m2
63
50
  return magnitude( amount + m2.amount ) if quantity == m2.quantity
64
51
  return self if m2.equal? SY::ZERO
65
- # o1, o2 = m2.coerce( self )
66
- # return o1.add o2
67
- raise SY::QuantityError, "Unable to perform #add with #{m2.quantity}!"
52
+ fail SY::QuantityError, "Unable to perform #add with #{m2.quantity}!"
68
53
  end
69
54
 
70
55
  # For absolute magnitudes, #- method always returns a result framed in
71
56
  # corresponding relative quantity.
72
57
  #
73
- # TODO: Figure out which module comes on the top in Quantity@Magnitude, whether Magnitude
74
- # or SignedMagnitude, and therefore, whether it is necessary to adjust this method.
75
58
  def - m2
76
59
  return magnitude amount - m2.amount if m2.quantity == quantity.relative
77
60
  return quantity.relative.magnitude( amount - m2.amount ) if
78
61
  quantity == m2.quantity
79
62
  return self if m2.equal? SY::ZERO
80
- # o1, o2 = m2.coerce( self )
81
- # return o1 - o2
82
- raise( SY::QuantityError, "Unable to perform #{quantity} - #{m2.quantity}!" )
63
+ fail SY::QuantityError, "Unable to perform #{quantity} - #{m2.quantity}!"
83
64
  end
84
65
 
85
66
  # Subtraction of absolute magnitudes that returns a result framed as
@@ -89,9 +70,7 @@ module SY::AbsoluteMagnitude
89
70
  def subtract m2
90
71
  return magnitude( amount + m2.amount ) if quantity == m2.quantity
91
72
  return self if m2.equal? SY::ZERO
92
- # o1, o2 = m2.coerce( self )
93
- # return o1.subtract o2
94
- raise( SY::QuantityError, "Unable to perform #add with #{m2.quantity}!" )
73
+ fail SY::QuantityError, "Unable to perform #add with #{m2.quantity}!"
95
74
  end
96
75
 
97
76
  # "Subtraction" of absolute magnitudes, that never takes more thant the
@@ -112,7 +91,5 @@ module SY::AbsoluteMagnitude
112
91
 
113
92
  # String describing this class.
114
93
  #
115
- def çς
116
- "Magnitude"
117
- end
94
+ def çς; "Magnitude" end
118
95
  end # class SY::AbsoluteMagnitude
@@ -28,8 +28,8 @@ class SY::Composition < Hash
28
28
  ꜧ.reject! { |_, exp| exp == 0 }
29
29
  }
30
30
 
31
- # FIXME: This quick fix simplification rule simplifies MoleAmount and
32
- # LitreVolume into Molarity. This solution is insufficiently systematic.
31
+ # This simplification rule simplifies MoleAmount and LitreVolume into
32
+ # Molarity.
33
33
  #
34
34
  SR << -> ꜧ {
35
35
  begin
@@ -61,8 +61,8 @@ class SY::Composition < Hash
61
61
  return ꜧ
62
62
  }
63
63
 
64
- # FIXME: This quick fix simplification rule simplifies LitreVolume times
65
- # Molarity into MoleAmount. This solution is insufficiently systematic.
64
+ # This simplification rule simplifies LitreVolume times Molarity into
65
+ # MoleAmount.
66
66
  #
67
67
  SR << -> ꜧ {
68
68
  begin
@@ -130,8 +130,6 @@ class SY::Composition < Hash
130
130
  # is a base dimension.
131
131
  #
132
132
  def atomic?
133
- puts "composition is #{self}" if SY::DEBUG
134
- puts "first[0].dimension is #{first[0].dimension}" if SY::DEBUG
135
133
  singular? && first[0].dimension.base?
136
134
  end
137
135
 
@@ -206,9 +204,8 @@ class SY::Composition < Hash
206
204
  #
207
205
  def simplify
208
206
  ꜧ = self.to_hash
209
- puts "simplifying #{ꜧ}" if SY::DEBUG
210
207
  SIMPLIFICATION_RULES.each { |rule| rule.( ꜧ ) }
211
- self.class[ ꜧ ].tap { |_| puts "result is #{_}" if SY::DEBUG }
208
+ self.class[ ꜧ ]
212
209
  end
213
210
 
214
211
  # Returns the quantity appropriate to this composition.
@@ -236,15 +233,8 @@ class SY::Composition < Hash
236
233
  # of the pertinent standard quantity.)
237
234
  #
238
235
  def infer_measure
239
- puts "#infer_measure; hash is #{self}" if SY::DEBUG
240
236
  map do |qnt, exp|
241
- puts "#infer_measure: doing quantity #{qnt} with exponent #{exp}!" if SY::DEBUG
242
- if qnt.standardish? then
243
- puts "#{qnt} standardish" if SY::DEBUG
244
- SY::Measure.identity
245
- else
246
- puts "#{qnt} not standardish" if SY::DEBUG
247
- puts "its measure is #{qnt.measure}, class #{qnt.measure.class}" if SY::DEBUG
237
+ if qnt.standardish? then SY::Measure.identity else
248
238
  qnt.measure( of: qnt.standard ) ** exp
249
239
  end
250
240
  end.reduce( SY::Measure.identity, :* )
@@ -265,18 +255,13 @@ class SY::Composition < Hash
265
255
  #
266
256
  def expand
267
257
  return self if irreducible?
268
- puts "#expand: #{self} not irreducible" if SY::DEBUG
269
258
  self.class[ reduce( self.class.empty ) { |cᴍ, pair|
270
259
  qnt, exp = pair
271
- puts "#expand: qnt: #{qnt}, exp: #{exp}" if SY::DEBUG
272
- puts "cᴍ is #{cᴍ}" if SY::DEBUG
273
260
  ( cᴍ + if qnt.irreducible? then
274
261
  self.class.singular( qnt ) * exp
275
262
  else
276
263
  qnt.composition * exp
277
- end.tap { |x| puts "Adding #{x}." if SY::DEBUG }
278
- ).tap { |x| puts "Result is #{x}." if SY::DEBUG }
264
+ end )
279
265
  } ]
280
- .tap{ |rslt| puts "#expand: result is #{rslt}" if SY::DEBUG }
281
266
  end
282
267
  end # class SY::Composition
@@ -39,9 +39,7 @@ class SY::Dimension
39
39
 
40
40
  # Presents class-owned instances (array).
41
41
  #
42
- def instances
43
- return @instances ||= []
44
- end
42
+ def instances; return @instances ||= [] end
45
43
 
46
44
  # Base dimension constructor. Base dimension symbol is expeced as argument.
47
45
  #
@@ -23,7 +23,7 @@ module SY::ExpressibleInUnits
23
23
  im = instance_method ß
24
24
  warn w unless ::SY::ExpressibleInUnits.method_family.include? im if
25
25
  ꜧ[ß].warns? unless instance_variable_get( :@no_collision ) == ß
26
- instance_variable_set( :@no_collision, nil ) # FIXME: This is too clumsy
26
+ instance_variable_set( :@no_collision, nil )
27
27
  else
28
28
  warn w if ꜧ[ß].warns?
29
29
  end
@@ -33,7 +33,7 @@ module SY::ExpressibleInUnits
33
33
  im = instance_method ß
34
34
  warn w unless ::SY::ExpressibleInUnits.method_family.include? im if
35
35
  ꜧ[ß].warns? unless instance_variable_get( :@no_collision ) == ß
36
- instance_variable_set( :@no_collision, nil ) # FIXME: This is too clumsy
36
+ instance_variable_set( :@no_collision, nil )
37
37
  else
38
38
  warn w if ꜧ[ß].warns?
39
39
  end
@@ -83,10 +83,7 @@ module SY::ExpressibleInUnits
83
83
  def known_units
84
84
  begin
85
85
  unit_namespace.instances
86
- rescue NoMethodError
87
- [] # no #instances method defined yet
88
- end
89
- .tap { |r| puts "Known units are #{r}" if SY::DEBUG }
86
+ rescue NoMethodError; [] end
90
87
  end
91
88
 
92
89
  # All methods defined by this mixin.
@@ -98,7 +95,6 @@ module SY::ExpressibleInUnits
98
95
  # Find unit based on name / abbreviation.
99
96
  #
100
97
  def find_unit ς
101
- puts "searching for unit #{ς}" if SY::DEBUG
102
98
  known_units.find do |u|
103
99
  u.name.to_s.downcase == ς.downcase &&
104
100
  ( ς == ς.downcase || ς == ς.upcase ) ||
@@ -109,7 +105,6 @@ module SY::ExpressibleInUnits
109
105
  # Return prefix method or empty string, if prefix method not necessary.
110
106
  #
111
107
  def prefix_method_string prefix
112
- puts "About to call PREFIX TABLE.to_full with #{prefix}" if SY::DEBUG
113
108
  full_prefix = SY::PREFIX_TABLE.to_full( prefix )
114
109
  full_prefix == '' ? '' : ".#{full_prefix}"
115
110
  end
@@ -126,19 +121,12 @@ module SY::ExpressibleInUnits
126
121
  super if ß.to_s =~ /to_.+/ # dissmiss :to_..., esp. :to_ary
127
122
  begin # prevent recurrent call of method_missing for the same symbol
128
123
  anti_recursion_exec token: ß, var: :@SY_Units_mmiss do
129
- puts "Method missing: '#{ß}'" if SY::DEBUG
130
124
  prefixes, units, exps = parse_unit_symbol ß
131
- # Define the unit method on self.class:
132
- # I'D HAVE TO PERFORM THE COLLISION CHECK HERE
133
- # IF NO COLLISION, INFORM THE SUBSEQUENT METHOD DEFINED CALL ON
134
- # SELF.CLASS
135
- puts "parsed" if SY::DEBUG
136
- self.class.instance_variable_set "@no_collision", ß # FIXME: This is too clumsy
125
+ self.class.instance_variable_set "@no_collision", ß
137
126
  self.class.module_eval write_unit_method( ß, prefixes, units, exps )
138
127
  SY::ExpressibleInUnits.method_family << self.class.instance_method( ß )
139
128
  end
140
129
  rescue NameError => err
141
- puts "NameError raised: #{err}" if SY::DEBUG
142
130
  super # give up
143
131
  rescue SY::ExpressibleInUnits::RecursionError
144
132
  super # give up
@@ -167,7 +155,6 @@ module SY::ExpressibleInUnits
167
155
  # figures out which SY units it represents, along with prefixes and exponents.
168
156
  #
169
157
  def parse_unit_symbol ß
170
- puts "About to parse #{ß} using all prefixes" if SY::DEBUG
171
158
  SY::Unit.parse_sps_using_all_prefixes( ß ) # rely on SY::Unit
172
159
  end
173
160
 
@@ -176,12 +163,10 @@ module SY::ExpressibleInUnits
176
163
  # Arrays must be of equal length. (Note: 'ß' is 'symbol', 'ς' is 'string')
177
164
  #
178
165
  def write_unit_method ß, prefixes, units, exponents
179
- puts "writing unit method #{ß}" if SY::DEBUG
180
166
  # Prepare prefix / unit / exponent triples for making factor strings:
181
167
  triples = [ prefixes, units, exponents ].transpose
182
168
  # A procedure for triple processing before use:
183
169
  process_triple = lambda do |pfx, unit_ς, exp|
184
- puts "Processing triple #{pfx}, #{unit_ς}, #{exp}." if SY::DEBUG
185
170
  [ ::SY::ExpressibleInUnits.find_unit( unit_ς ).name.to_s.upcase,
186
171
  ::SY::ExpressibleInUnits.prefix_method_string( pfx ),
187
172
  ::SY::ExpressibleInUnits.exponentiation_string( exp ) ]
@@ -211,7 +196,7 @@ module SY::ExpressibleInUnits
211
196
  method_body = factors.join( " * \n " )
212
197
  end
213
198
  # Return the finished method string:
214
- return ( method_skeleton % method_body ).tap { |ς| puts ς if SY::DEBUG }
199
+ return ( method_skeleton % method_body )
215
200
  end
216
201
 
217
202
  # Takes a token as the first argument, a symbol of the instance variable to
@@ -230,9 +215,4 @@ module SY::ExpressibleInUnits
230
215
  registry.delete token
231
216
  end
232
217
  end
233
-
234
- # FIXME: There should be an option to define by default, already at the
235
- # beginning, certain methods for certain classes, to get in front of possible
236
- # collisions. Collision was detected for example for #second with
237
- # active_support/duration.rb
238
218
  end
@@ -18,22 +18,16 @@ module SY
18
18
  class << BASE_DIMENSIONS
19
19
  # Letters of the base dimensions.
20
20
  #
21
- def letters
22
- keys
23
- end
21
+ def letters; keys end
24
22
 
25
23
  # Base dimensions letters with prefixes. (Remark: I forgot what did I mean
26
24
  # those prefixes for. Something important, I just forgot what.)
27
25
  #
28
- def prefixed_letters
29
- [] # none for now
30
- end
26
+ def prefixed_letters; [] end
31
27
 
32
28
  # Base dimension symbols – letters and prefixed letters.
33
29
  #
34
- def base_symbols
35
- @baseß ||= letters + prefixed_letters
36
- end
30
+ def base_symbols; @baseß ||= letters + prefixed_letters end
37
31
  alias basic_symbols base_symbols
38
32
 
39
33
  # Takes an sps representing a dimension, and converts it to a hash of
@@ -45,7 +39,7 @@ module SY
45
39
  end
46
40
  end
47
41
 
48
- # Table of standard prefixes and their corresponding unit multiples.
42
+ # Table of standard prefixes and their corresponding unit multiples.
49
43
  #
50
44
  PREFIX_TABLE = [ { full: "exa", short: "E", factor: 1e18 },
51
45
  { full: "peta", short: "P", factor: 1e15 },
@@ -144,9 +138,7 @@ module SY
144
138
  SUPERSCRIPT = Hash.new { |ꜧ, key|
145
139
  if key.is_a? String then
146
140
  key.size <= 1 ? nil : key.each_char.map{|c| ꜧ[c] }.join
147
- else
148
- ꜧ[key.to_s]
149
- end
141
+ else ꜧ[key.to_s] end
150
142
  }.merge! Hash[ '-/0123456789'.each_char.zip( '⁻⎖⁰¹²³⁴⁵⁶⁷⁸⁹'.each_char ) ]
151
143
 
152
144
  # Reverse conversion of Unicode superscript exponents (from exponent
@@ -155,9 +147,7 @@ module SY
155
147
  SUPERSCRIPT_DOWN = Hash.new { |ꜧ, key|
156
148
  if key.is_a? String then
157
149
  key.size == 1 ? nil : key.each_char.map{|c| ꜧ[c] }.join
158
- else
159
- ꜧ[key.to_s]
160
- end
150
+ else ꜧ[key.to_s] end
161
151
  }.merge!( SUPERSCRIPT.invert ).merge!( '¯' => '-', # other superscript chars
162
152
  '´' => '/' )
163
153
 
@@ -265,124 +265,16 @@ module SY::Magnitude
265
265
 
266
266
  #
267
267
  def to_s( unit=quantity.units.first || quantity.standard_unit,
268
- number_format=default_amount_format ) # FIXME: TUTO JE TO KUREVSTVO TU SA TA JEDNOTKA KONSTRUUJE
269
- puts "#to_s called on a magnitude of quantity #{quantity}" if SY::DEBUG
270
- # step 1: produce pairs [number, unit_presentation],
271
- # where unit_presentation is an array of triples
272
- # [prefix, unit, exponent], which together give the
273
- # correct dimension for this magnitude, and correct
274
- # factor so that number * factor == self.amount
275
- # step 2: define a goodness function for them
276
- # step 3: define a satisfaction criterion
277
- # step 4: maximize this goodness function until the satisfaction
278
- # criterion is met
279
- # step 5: interpolate the string from the chosen choice
280
-
281
- # so, let's start doing it
282
- # how do we produce the first choice?
283
- # if the standard unit for this quantity is named, we'll start with it
284
-
285
- # let's say that the abbreviation of this std. unit is Uu, so the first
286
- # choices will be:
287
- #
288
- # amount.Uu
289
- # (amount * 1000).µUu
290
- # (amount / 1000).kUu
291
- # (amount * 1_000_000).nUu
292
- # (amount / 1_000_000).MUu
293
- # ...
294
- #
295
- # (let's say we'll use only short prefixes)
296
- #
297
- # which one do we use?
298
- # That depends. For example, CelsiusTemperature is never rendered with
299
- # SI prefixes, so their cost should be +Infinity
300
- #
301
- # Cost of the number could be eg.:
302
- #
303
- # style: cost:
304
- # 3.141 0
305
- # 31.41, 314.1 1
306
- # 0.3141 2
307
- # 3141.0 3
308
- # 0.03141 4
309
- # 31410.0 5n
310
- # 0.003141 6
311
- # ...
312
- #
313
- # Default cost of prefixes could be eg.
314
- #
315
- # unit representation: cost:
316
- # U 0
317
- # dU +Infinity
318
- # cU +Infinity
319
- # mU 1
320
- # dkU +Infinity
321
- # hU +Infinity
322
- # kU 1
323
- # µU 2
324
- # MU 2
325
- # nU 3
326
- # GU 3
327
- # pU 4
328
- # TU 4
329
- # fU 5
330
- # PU 5
331
- # aU 6
332
- # EU 6
333
- #
334
- # Cost of exponents could be eg. their absolute value, and +1 for minus sign
335
- #
336
- # Same unit with two different prefixes may never be used (cost +Infinity)
337
- #
338
- # Afterwards, there should be cost of inconsistency. This could be implemented
339
- # eg. as computing the first 10 possibilities for amount: 1 and giving them
340
- # bonuses -20, -15, -11, -8, -6, -5, -4, -3, -2, -1. That would further reduce the variability of the
341
- # unit representations.
342
- #
343
- # Commenting again upon default cost of prefixes, prefixes before second:
344
- #
345
- # prefix: cost:
346
- # s 0
347
- # ms 4
348
- # ns 5
349
- # ps 6
350
- # fs 7
351
- # as 9
352
- # ks +Infinity
353
- # Ms +Infinity
354
- # ...
355
- #
356
- # Prefixes before metre
357
- #
358
- # prefix: cost:
359
- # m 0
360
- # mm 2
361
- # µm 2
362
- # nm 3
363
- # km 3
364
- # Mm +Infinity
365
- # ...
366
- #
367
-
368
- # number, unit_presentation = choice
369
-
370
- # return "#{amount} of #{quantity}"
371
-
268
+ number_format=default_amount_format )
372
269
  begin
373
-
374
270
  un = unit.short || unit.name
375
-
376
271
  if un then
377
272
  number = self.in unit
378
273
  number_ς = number_format % number
379
-
380
274
  prefix = ''
381
275
  exp = 1
382
276
  # unit_presentation = prefix, unit, exp
383
-
384
277
  unit_ς = SY::SPS.( [ "#{prefix}#{unit.short}" ], [ exp ] )
385
-
386
278
  [ number_ς, unit_ς ].join '.'
387
279
  else
388
280
  number = amount
@@ -406,7 +298,6 @@ module SY::Magnitude
406
298
  return number_ς if unit_ς == '' || unit_ς == 'unit'
407
299
  [ number_ς, unit_ς ].join '.'
408
300
  end
409
-
410
301
  rescue
411
302
  fail
412
303
  number_ς = number_format % amount
@@ -414,29 +305,9 @@ module SY::Magnitude
414
305
  end
415
306
  end
416
307
 
417
- # def to_s unit=quantity.units.first, number_format='%.3g'
418
- # begin
419
- # return to_string( unit ) if unit and unit.abbreviation
420
- # rescue
421
- # end
422
- # # otherwise, use units of basic dimensions – here be the magic:
423
- # hsh = dimension.to_hash
424
- # symbols, exponents = hsh.each_with_object Hash.new do |pair, memo|
425
- # dimension_letter, exponent = pair
426
- # std_unit = SY::Dimension.basic( dimension_letter ).standard_unit
427
- # memo[ std_unit.abbreviation || std_unit.name ] = exponent
428
- # end.to_a.transpose
429
- # # assemble the superscripted product string:
430
- # sps = SY::SPS.( symbols, exponents )
431
- # # and finally, interpolate the string
432
- # "#{number_format}#{sps == '' ? '' : '.' + sps}" % amount
433
- # "#{amount}#{sps == '' ? '' : '.' + sps}"
434
- # end
435
-
436
308
  # Inspect string of the magnitude
437
309
  #
438
310
  def inspect
439
- puts "inspect called on a magnitude of quantity #{quantity}" if SY::DEBUG
440
311
  "#<#{çς}: #{self} >"
441
312
  end
442
313
 
@@ -12,15 +12,11 @@ class SY::Measure
12
12
  class << self
13
13
  # Identity measure.
14
14
  #
15
- def identity
16
- simple_scale 1
17
- end
15
+ def identity; simple_scale 1 end
18
16
 
19
17
  # Simple scaling measure. (Eg. pounds vs kilograms)
20
18
  #
21
- def simple_scale scale
22
- new( ratio: scale )
23
- end
19
+ def simple_scale scale; new( ratio: scale ) end
24
20
 
25
21
  # Simple offset measure. (Such as °C)
26
22
  #
@@ -89,11 +85,8 @@ class SY::Measure
89
85
  # Inverse measure.
90
86
  #
91
87
  def inverse
92
- if ratio.nil? then
93
- self.class.new( r: w, w: r ) # swap closures
94
- else
95
- self.class.new( ratio: 1 / ratio )
96
- end
88
+ if ratio.nil? then self.class.new( r: w, w: r ) # swap closures
89
+ else self.class.new( ratio: 1 / ratio ) end
97
90
  end
98
91
 
99
92
  # Measure composition (like f * g function composition).
@@ -65,9 +65,7 @@ class Matrix
65
65
  def /(other)
66
66
  case other
67
67
  when Numeric
68
- rows = @rows.collect {|row|
69
- row.collect {|e| e / other }
70
- }
68
+ rows = @rows.collect do |row| row.collect {|e| e / other } end
71
69
  return new_matrix rows, column_count
72
70
  when Matrix
73
71
  return self * other.inverse
@@ -87,11 +87,8 @@ class SY::Measure
87
87
  # Inverse measure.
88
88
  #
89
89
  def inverse
90
- if ratio.nil? then
91
- self.class.new( r: w, w: r ) # swap closures
92
- else
93
- self.class.new( ratio: 1 / ratio )
94
- end
90
+ if ratio.nil? then self.class.new( r: w, w: r ) # swap closures
91
+ else self.class.new( ratio: 1 / ratio ) end
95
92
  end
96
93
 
97
94
  # Measure composition (like f * g function composition).
@@ -101,9 +98,7 @@ class SY::Measure
101
98
  r1, r2, w1, w2 = r, other.r, w, other.w
102
99
  self.class.new( r: lambda { |ref_amnt| r1.( r2.( ref_amnt ) ) },
103
100
  w: lambda { |amnt| w2.( w1.( amnt ) ) } )
104
- else
105
- self.class.new( ratio: ratio * other.ratio )
106
- end
101
+ else self.class.new( ratio: ratio * other.ratio ) end
107
102
  end
108
103
 
109
104
  # Measure composition with inverse of another measure.
@@ -5,10 +5,6 @@
5
5
  class SY::Quantity
6
6
  include NameMagic
7
7
 
8
- # name_set_hook do |name, new_instance, old_name|
9
- # new_instance.protect!; name
10
- # end
11
-
12
8
  RELATIVE_QUANTITY_NAME_SUFFIX = "±"
13
9
 
14
10
  attr_reader :MagnitudeModule, :Magnitude, :Unit
@@ -38,7 +34,6 @@ class SY::Quantity
38
34
  #
39
35
  def standard( of: nil )
40
36
  fail ArgumentError, "Dimension (:of argument) must be given!" if of.nil?
41
- puts "Constructing standard quantity of #{of} dimension" if SY::DEBUG
42
37
  return SY.Dimension( of ).standard_quantity
43
38
  end
44
39
 
@@ -64,14 +59,11 @@ class SY::Quantity
64
59
  coerces: [],
65
60
  coerces_to: [],
66
61
  **nn )
67
- puts "Quantity init relative: #{relative}, composition: #{composition}, measure: #{measure}, #{nn}" if SY::DEBUG
68
62
  @units = [] # array of units as favored by this quantity
69
63
  @relative = relative
70
64
  if composition.nil? then
71
- puts "Composition not given, dimension expected." if SY::DEBUG
72
65
  @dimension = SY.Dimension( of )
73
66
  else
74
- puts "Composition received (#{composition})." if SY::DEBUG
75
67
  @composition = SY::Composition[ composition ]
76
68
  @dimension = @composition.dimension
77
69
  end
@@ -86,9 +78,6 @@ class SY::Quantity
86
78
  end
87
79
  coerces( *Array( coerces ) )
88
80
  Array( coerces_to ).each { |qnt| qnt.coerces self }
89
- puts "Composition of the initialized instance is #{composition}." if SY::DEBUG
90
- puts "Initialized instance is #{relative? ? :relative : :absolute}" if SY::DEBUG
91
- puts "Initialized instance object_id is #{object_id}" if SY::DEBUG
92
81
  end
93
82
 
94
83
  # Simple quantity is one with simple composition. If nontrivial composition
@@ -193,21 +182,15 @@ class SY::Quantity
193
182
  #
194
183
  def measure( of: nil )
195
184
  return @measure if of.nil? # act as simple getter if :of not specified
196
- puts "#{self.inspect} asked about measure of #{of}" if SY::DEBUG
197
185
  return SY::Measure.identity if of == self or of == colleague
198
- raise SY::DimensionError, "#{self} vs. #{of}!" unless same_dimension? of
186
+ fail SY::DimensionError, "#{self} vs. #{of}!" unless same_dimension? of
199
187
  return of.measure( of: of.standard ).inverse if standardish?
200
188
  m = begin
201
- puts "composition is #{composition}, class #{composition.class}" if SY::DEBUG
202
- measure ||
203
- colleague.measure ||
204
- composition.infer_measure
189
+ measure || colleague.measure || composition.infer_measure
205
190
  rescue NoMethodError
206
191
  fail SY::QuantityError, "Measure of #{of} by #{self} impossible!"
207
192
  end
208
193
  return m if of.standardish?
209
- puts "#{of} not standardish, obtained measure relates to #{standard}, and " +
210
- "it will have to be extended to #{of}." if SY::DEBUG
211
194
  return m * standard.measure( of: of )
212
195
  end
213
196
 
@@ -266,11 +249,7 @@ class SY::Quantity
266
249
  # Constructs a absolute magnitude of this quantity.
267
250
  #
268
251
  def magnitude amount
269
- puts "self.object_id is #{object_id}" if SY::DEBUG
270
- puts "composition is #{composition}" if SY::DEBUG
271
- puts "Constructing #{self}#magnitude with amount #{amount}." if SY::DEBUG
272
252
  Magnitude().new( of: self, amount: amount )
273
- .tap { puts "#{self}#magnitude constructed!" if SY::DEBUG }
274
253
  end
275
254
 
276
255
  # Constructs a new unit of this quantity.
@@ -307,7 +286,6 @@ class SY::Quantity
307
286
  # Quantity multiplication.
308
287
  #
309
288
  def * q2
310
- puts "#{self.name} * #{q2.name}" if SY::DEBUG
311
289
  rel = [ self, q2 ].any? &:relative
312
290
  ( SY::Composition[ self => 1 ] + SY::Composition[ q2 => 1 ] )
313
291
  .to_quantity relative: rel
@@ -316,7 +294,6 @@ class SY::Quantity
316
294
  # Quantity division.
317
295
  #
318
296
  def / q2
319
- puts "#{self.name} / #{q2.name}" if SY::DEBUG
320
297
  rel = [ self, q2 ].any? &:relative?
321
298
  ( SY::Composition[ self => 1 ] - SY::Composition[ q2 => 1 ] )
322
299
  .to_quantity relative: rel
@@ -325,7 +302,6 @@ class SY::Quantity
325
302
  # Quantity raising to a number.
326
303
  #
327
304
  def ** num
328
- puts "#{self.name} ** #{num}" if SY::DEBUG
329
305
  SY::Composition[ self => num ].to_quantity relative: relative?
330
306
  end
331
307
 
@@ -344,8 +320,6 @@ class SY::Quantity
344
320
  # Returns the standard quantity for this quantity's dimension.
345
321
  #
346
322
  def standard
347
- puts "Dimension of this quantity is #{dimension}" if SY::DEBUG
348
- puts "Its standard quantity is #{dimension.standard_quantity}" if SY::DEBUG
349
323
  dimension.standard_quantity
350
324
  end
351
325
 
@@ -397,21 +371,16 @@ class SY::Quantity
397
371
  # Main parametrized (ie. quantity-specific) module for magnitudes.
398
372
  #
399
373
  def MagnitudeModule
400
- puts "#{self}#MagnitudeModule called" if SY::DEBUG
401
374
  @MagnitudeModule ||= if absolute? then
402
375
  Module.new { include SY::Magnitude }
403
- else
404
- absolute.MagnitudeModule
405
- end
376
+ else absolute.MagnitudeModule end
406
377
  end
407
378
 
408
379
  # Parametrized magnitude class.
409
380
  #
410
381
  def Magnitude
411
- puts "#{self}#Magnitude called" if SY::DEBUG
412
382
  @Magnitude or
413
- ( puts "Constructing #{self}@Magnitude parametrized class" if SY::DEBUG
414
- mmod = MagnitudeModule()
383
+ ( mmod = MagnitudeModule()
415
384
  mixin = relative? ? SY::SignedMagnitude : SY::AbsoluteMagnitude
416
385
  qnt_ɴ_λ = -> { name ? "#{name}@%s" : "#<Quantity:#{object_id}@%s>" }
417
386
 
@@ -439,18 +408,15 @@ class SY::Quantity
439
408
  # Parametrized unit class.
440
409
  #
441
410
  def Unit
442
- puts "#{self}#Unit called" if SY::DEBUG
443
- @Unit ||= ( puts "Constructing #{self}@Unit parametrized class" if SY::DEBUG
444
- if relative? then absolute.Unit else
411
+ @Unit ||= ( if relative? then absolute.Unit else
445
412
  qnt = self
446
413
  ɴλ = -> { name ? "#{name}@%s" : "#<Quantity:#{object_id}@%s>" }
447
414
 
448
- Class.new Magnitude() do puts "Creating @Unit class!" if SY::DEBUG
449
- include SY::Unit; puts "Included SY::Unit" if SY::DEBUG
415
+ Class.new Magnitude() do
416
+ include SY::Unit
450
417
 
451
418
  singleton_class.class_exec do
452
419
  define_method :standard do |**nn| # Customized #standard.
453
- puts "parametrized #{qnt}@Unit#standard called" if SY::DEBUG
454
420
  @standard ||= new **nn.update( of: qnt )
455
421
  end
456
422
 
@@ -462,20 +428,15 @@ class SY::Quantity
462
428
  unit_parametrized_subclass.namespace = SY::Unit
463
429
  end
464
430
  end ).tap do |u|
465
- puts "@Unit constructed, its namespace is #{u.namespace}" if SY::DEBUG
466
- puts "its instances are #{u.namespace.instances}" if SY::DEBUG
467
- puts "its instance names are #{u.namespace.instance_names}" if SY::DEBUG
468
431
  end
469
432
  end
470
433
 
471
434
  private
472
435
 
473
436
  def construct_colleague
474
- puts "#{self}#construct_colleague" if SY::DEBUG
475
437
  ɴ = name
476
438
  ʀsuffix = SY::Quantity::RELATIVE_QUANTITY_NAME_SUFFIX
477
439
  rel = relative?
478
- puts "#{self} is #{rel ? 'relative' : 'absolute'}" if SY::DEBUG
479
440
  # Here, it is impossible to rely on Composition::QUANTITY_TABLE –
480
441
  # on the contrary, the table relies on Quantity#colleague.
481
442
  constr_ɴ = ->( ɴ, ʀ ) { ç.new composition: composition, ɴ: ɴ, relative: ʀ }
@@ -7,31 +7,20 @@ module SY::SignedMagnitude
7
7
  # :amount argument. Amount is allowed to be negative.
8
8
  #
9
9
  def initialize( of: nil, amount: nil )
10
- puts "Constructing AbsoluteMagnitude of #{of}, amount: #{amount}" if SY::DEBUG
11
10
  fail ArgumentError, "Quantity (:of) argument missing!" if of.nil?
12
11
  @quantity = of
13
12
  @amount = case amount
14
- when Numeric then
15
- puts "This amount is a Numeric, using it directly" if SY::DEBUG
16
- amount
17
- when nil then
18
- puts "This amount is 'nil', using 1 instead" if SY::DEBUG
19
- 1
13
+ when Numeric then amount
14
+ when nil then 1
20
15
  else
21
16
  begin
22
- puts "Amount #{amount} will be reframed to #{@quantity}" if SY::DEBUG
23
17
  amount.( @quantity ).amount
24
- rescue NameError, NoMethodError
25
- puts "fail, amount #{amount} will be used directly" if SY::DEBUG
26
- amount
27
- end
18
+ rescue NameError, NoMethodError; amount end
28
19
  end
29
20
  end
30
21
 
31
22
  # Addition.
32
23
  #
33
- # TODO: Figure out which module comes on the top in Quantity@Magnitude, whether Magnitude
34
- # or SignedMagnitude, and therefore, whether it is necessary to adjust this method.
35
24
  def + m2
36
25
  return magnitude( amount + m2.amount ) if quantity == m2.quantity
37
26
  return quantity.absolute.magnitude( amount + m2.amount ) if
@@ -42,7 +31,6 @@ module SY::SignedMagnitude
42
31
 
43
32
  # Subtraction.
44
33
  #
45
- # TODO: ditto
46
34
  def - m2
47
35
  return magnitude( amount - m2.amount ) if m2.quantity == quantity.relative
48
36
  return quantity.relative.magnitude( amount - m2.amount ) if
@@ -46,16 +46,12 @@ module SY::Unit
46
46
  w = SY::ExpressibleInUnits::COLLISION_WARNING
47
47
  SY::ExpressibleInUnits.included_in.each do |modul|
48
48
  im = modul.instance_methods
49
- # puts ɱ, "class: #{ɱ.class}"
50
- # puts im.size
51
- # puts down
52
- # puts im.include? down
53
49
  warn w % [down, modul] if im.include? down
54
50
  abbrev = new_instance.abbreviation
55
51
  warn w % [abbrev, modul] if im.include? abbrev
56
52
  end
57
53
  end
58
- up.to_sym.tap { |sym| puts "name_set_hook #{sym}" if SY::DEBUG }
54
+ up.to_sym
59
55
  end
60
56
 
61
57
  # We'll now define all the prefix methods on the target (#mili, #mega...),
@@ -94,7 +90,6 @@ module SY::Unit
94
90
  # special meaning of setting the relationship of that quantity.
95
91
  #
96
92
  def standard( of: nil, **nn )
97
- puts "Constructing a standard unit of #{of}." if SY::DEBUG
98
93
  fail ArgumentError, ":of argument missing!" if of.nil?
99
94
  qnt = SY::Quantity.instance( of )
100
95
  nn.empty? ? qnt.standard_unit : qnt.new_standard_unit( **nn )
@@ -110,7 +105,7 @@ module SY::Unit
110
105
  # Full list of known unit names and unit abbreviations.
111
106
  #
112
107
  def known_symbols
113
- instance_names.map( &:downcase ) + abbreviations.keys
108
+ instances.names( false ).map( &:downcase ) + abbreviations.keys
114
109
  end
115
110
 
116
111
  # Parses an SPS, curring it with known unit names and abbreviations,
@@ -156,13 +151,6 @@ module SY::Unit
156
151
  def initialize( short: nil, warns: true, **nn )
157
152
  @abbreviation = short.to_sym if short
158
153
  @warns = warns # does this unit care about blatant name collisions?
159
-
160
- # FIXME: Here, we would have to watch out for :amount being set
161
- # if it is a number, amount is in standard units
162
- # however, if it is a magnitude, especially one of another equidimensional quantity,
163
- # it estableshes a relationship between this and that quantity. It means that
164
- # the unit amount automatically becomes ... one ... and such relationship can
165
- # only be established for standard quantity
166
154
  super nn
167
155
  end
168
156
 
@@ -269,7 +257,5 @@ module SY::Unit
269
257
 
270
258
  # String describing this class.
271
259
  #
272
- def çς
273
- "Unit"
274
- end
260
+ def çς; "Unit" end
275
261
  end # class SY::Unit
@@ -1,7 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module SY
4
- VERSION = "2.1.2"
5
- DEBUG = false # debug mode switch - sometimes there are lines like
6
- # puts "something" if SY::DEBUG
4
+ VERSION = "2.1.4"
7
5
  end
@@ -1,21 +1,21 @@
1
1
  #! /usr/bin/ruby
2
2
  # encoding: utf-8
3
3
 
4
- # **************************************************************************
4
+ # *****************************************************************
5
5
  # THIS IS SPEC-STYLE TEST FILE FOR SY PHYSICAL UNITS LIBRARY
6
- # **************************************************************************
6
+ # *****************************************************************
7
7
 
8
8
  # The following will load Ruby spec-style library
9
9
  require 'mathn'
10
10
  require 'minitest/autorun'
11
11
 
12
12
  # The following will load SY library
13
- require 'sy'
14
- # require './../lib/sy'
13
+ # require 'sy'
14
+ require './../lib/sy'
15
15
 
16
- # **************************************************************************
16
+ # *****************************************************************
17
17
  # THE SPECIFICATIONS START HERE
18
- # **************************************************************************
18
+ # *****************************************************************
19
19
 
20
20
  describe SY do
21
21
  it "should have basic assets" do
@@ -253,7 +253,7 @@ describe SY::Quantity, SY::Magnitude do
253
253
  1.mm.to_s.must_equal "0.001.m"
254
254
  1.mm.inspect.must_equal "#<±Magnitude: 0.001.m >"
255
255
  1.µs.inspect.must_equal "#<±Magnitude: 1e-06.s >"
256
-
256
+
257
257
  SY::Area.dimension.must_equal SY.Dimension( :L² )
258
258
  SY::Area.composition.must_equal SY::Composition[ SY::Length => 2 ]
259
259
 
@@ -298,7 +298,7 @@ describe SY::Quantity, SY::Magnitude do
298
298
 
299
299
  q1.relative?.must_equal true
300
300
  q2.relative?.must_equal true
301
-
301
+
302
302
  q1.object_id.must_equal q2.object_id
303
303
  ( 1.s⁻¹ ).quantity.object_id.must_equal ( 1 / 1.s ).quantity.object_id
304
304
  ( 1 / 1.s ).must_equal 1.s⁻¹
@@ -312,9 +312,10 @@ describe SY::Quantity, SY::Magnitude do
312
312
  rescue
313
313
  end
314
314
  end.must_include :M
315
- SY::Unit.instance_names.must_include :MOLE
315
+ SY::Unit.instances.names( false ).must_include :MOLE
316
316
  # Avogadro's number is defined directly in SY
317
- 1.mol.quantity.object_id.must_equal SY::Nᴀ.unit.( SY::MoleAmount ).quantity.object_id
317
+ 1.mol.quantity.object_id
318
+ .must_equal SY::Nᴀ.unit.( SY::MoleAmount ).quantity.object_id
318
319
  SY::Nᴀ.unit.( SY::MoleAmount ).must_equal 1.mol
319
320
  0.7.mol.l⁻¹.amount.must_equal 0.7
320
321
  1.M.must_equal 1.mol.l⁻¹.( SY::Molarity )
@@ -325,7 +326,6 @@ describe SY::Quantity, SY::Magnitude do
325
326
  # Avogadro's number is defined directly in SY
326
327
  1.mol.must_equal SY::Nᴀ.unit.( SY::MoleAmount )
327
328
 
328
-
329
329
  0.7.M.must_equal 0.7.mol.l⁻¹.( SY::Molarity )
330
330
  # (if #is_actually! conversion method is not used, current
331
331
  # implementation will refuse to compare different quantities,
@@ -353,10 +353,17 @@ describe SY::Quantity, SY::Magnitude do
353
353
  # watt
354
354
  ( 1.V * 1.A ).( SY::Power ).must_be_within_epsilon 1.W, 1e-9
355
355
 
356
- # pretty representation
357
- ( 1.m / 3.s ).to_s.must_equal( "0.333.m.s⁻¹" )
358
- ( 1.m / 7.01e7.s ).to_s.must_equal( "1.43e-08.m.s⁻¹" )
356
+ # Custom unit creation
357
+ XOXO = SY::Unit.of SY::Volume, amount: 1.l
358
+ assert_equal 1.l.( SY::Volume ), 1.xoxo.( SY::Volume )
359
359
 
360
+ # TRIPLE_POINT_OF_WATER
361
+ assert_equal SY::TRIPLE_POINT_OF_WATER, 0.°C.( SY::Temperature )
362
+ assert_equal 273.15, 0.°C.in( :K )
363
+ assert_equal SY::Unit.instance( :SECOND ), SY::Unit.instance( :second )
364
+ assert_equal SY::TRIPLE_POINT_OF_WATER, 0.°C # coercion behavior
365
+
366
+ # other tests
360
367
  assert_equal 1.m, 1.s * 1.m.s⁻¹
361
368
  assert_equal 1.µM.s⁻¹, 1.µM / 1.s
362
369
  assert_equal 1.m.s⁻¹, 1.m.s( -1 )
@@ -367,64 +374,39 @@ describe SY::Quantity, SY::Magnitude do
367
374
  assert_equal SY::Amount( 1 ), 1.µM / ( 1.µM + 0.µM )
368
375
  assert_equal 1.µM, 1.µM * 1.µM / ( 1.µM + 0.µM )
369
376
  assert_in_epsilon 1.µM, 1.µmol / 1.dm( 3 ).( SY::LitreVolume )
370
-
377
+
371
378
  assert_equal SY::Molarity.relative, 1.mol.l⁻¹.quantity
372
379
  assert_equal SY::MoleAmount.relative, 1.M.l.quantity
373
380
 
381
+
374
382
  assert_equal 1 / SY::Time, 1 / SY::Time
375
383
  assert_equal 1 / SY::Time.relative, 1 / SY::Time
376
384
  assert_equal ( 1 / SY::Time.relative ), 1.mol.s⁻¹.( 1 / SY::Time ).quantity
377
385
  assert_equal ( 1 / SY::Time ).object_id,
378
- ( 1.0.µmol.min⁻¹.mg⁻¹ * 100.kDa ).( 1 / SY::Time ).quantity.object_id
386
+ ( 1.0.µmol.min⁻¹.mg⁻¹ * 100.kDa ).( 1 / SY::Time ).quantity.object_id
379
387
  assert_equal SY::Time.magnitude( 1 ), SY::SECOND
380
- assert_equal Matrix[[60.mM], [60.mM]], Matrix[[1e-03.s⁻¹.M], [1e-3.s⁻¹.M]] * 60.s
388
+ end
389
+
390
+ describe "pretty representation" do
391
+ it "should" do
392
+ ( 1.0.m / 3.s ).to_s.must_be_kind_of String
393
+ ( 1.0.m / 3.s ).to_s.must_equal "0.333.m.s⁻¹"
394
+
395
+ ( 1.m / 7.01e7.s ).to_s.must_equal( "1.43e-08.m.s⁻¹" )
396
+ end
397
+ end
398
+
399
+ describe "matrix integration" do
400
+ it "should" do
401
+ assert_equal Matrix[[60.mM], [60.mM]], Matrix[[1e-03.s⁻¹.M], [1e-3.s⁻¹.M]] * 60.s
381
402
 
382
- assert_equal Matrix[[5.m]], Matrix[[1.m.s⁻¹, 2.m.s⁻¹]] * Matrix.column_vector( [1.s, 2.s] )
383
- assert_equal Matrix[[2.m, 3.m], [4.m, 5.m]],
384
- Matrix[[1.m, 2.m], [3.m, 4.m]] + Matrix[[1.m, 1.m], [1.m, 1.m]]
385
- assert_equal Matrix[[5.µM]], Matrix[[1.µM]] + Matrix[[2.µM.s⁻¹]] * Matrix[[2.s]]
386
- assert_equal Matrix[[1.s]], Matrix[[1]] * 1.s
387
- assert_equal Matrix[[1.s]], 1.s * Matrix[[1]]
388
- XOXO = SY::Unit.of SY::Volume, amount: 1.l
389
- assert_equal 1.l.( SY::Volume ), 1.xoxo.( SY::Volume )
390
- assert_equal SY::TRIPLE_POINT_OF_WATER, 0.°C.( SY::Temperature )
391
- assert_equal 273.15, 0.°C.in( :K )
392
- assert_equal SY::Unit.instance( :SECOND ), SY::Unit.instance( :second )
393
- assert_equal SY::TRIPLE_POINT_OF_WATER, 0.°C # coercion behavior
394
- assert 2.°C.eql?( 1.°C + 1.K )
395
- assert ( 1.°C - 1.°C ).eql?( 0.K )
396
- assert_equal :raised, begin
397
- 1.°C + 1.°C
398
- :nothing_raised
399
- rescue QuantityError
400
- :raised
401
- end
402
- assert_equal :raised, begin
403
- 1.K + 1.°C
404
- :nothing_raised
405
- rescue QuantityError
406
- :raised
407
- end
408
- assert_equal :raised, begin
409
- 1.K - 1.°C
410
- :nothing_raised
411
- rescue QuantityError
412
- :raised
413
- end
414
- assert 1.mm.K⁻¹.eql?( 1.mm.°C⁻¹ )
415
- assert 1.mm.K.eql?( 1.mm.°C )
416
- assert_equal :raised, begin
417
- 1.mm / 1.°C
418
- :nothing_raised
419
- rescue QuantityError
420
- :raised
421
- end
422
- assert_equal :raised, begin
423
- 1.mm * 1.°C
424
- :nothing_raised
425
- rescue QuantityError
426
- :raised
427
- end
403
+ assert_equal Matrix[[5.m]], Matrix[[1.m.s⁻¹, 2.m.s⁻¹]] * Matrix.column_vector( [1.s, 2.s] )
404
+ assert_equal Matrix[[2.m, 3.m], [4.m, 5.m]],
405
+ Matrix[[1.m, 2.m], [3.m, 4.m]] + Matrix[[1.m, 1.m], [1.m, 1.m]]
406
+ assert_equal Matrix[[5.µM]], Matrix[[1.µM]] + Matrix[[2.µM.s⁻¹]] * Matrix[[2.s]]
407
+ assert_equal Matrix[[1.s]], Matrix[[1]] * 1.s
408
+ assert_equal Matrix[[1.s]], 1.s * Matrix[[1]]
409
+ end
428
410
  end
429
411
  end
430
412
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sy
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.2
4
+ version: 2.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boris Stitnicky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-20 00:00:00.000000000 Z
11
+ date: 2016-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler