sy 1.0.0 → 1.0.1
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 +4 -4
- data/lib/sy.rb +1 -1
- data/lib/sy/dimension.rb +3 -3
- data/lib/sy/expressible_in_units.rb +30 -41
- data/lib/sy/fixed_assets_of_the_module.rb +8 -17
- data/lib/sy/magnitude.rb +1 -1
- data/lib/sy/quantity.rb +5 -5
- data/lib/sy/version.rb +3 -2
- metadata +2 -3
- data/lib/sy/abstract_algebra.rb +0 -102
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10add7f2f0bf05cad700558533497d69933635d9
|
4
|
+
data.tar.gz: 3efd7b86cff1d12b78860996f8071b4ac3e657c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76cf82027239bdbdbf335adecafd877c9569be862ab6991514632c9eaf19241ab8a2c677acf7f908a7b2aef7a024221868172f8b663bc9c29fad6eaf1662aec0
|
7
|
+
data.tar.gz: 0416c7c76d69039e84976ede34a3714f0c3128eaf07a8a2fb423fbc837fbb65b2733899629670f159364f46160d10e115ac1924ae53272b502ca1c1fc31b2fce
|
data/lib/sy.rb
CHANGED
@@ -196,7 +196,7 @@ module SY
|
|
196
196
|
Molarity = ( MoleAmount / LitreVolume ).protect!
|
197
197
|
|
198
198
|
# Standard unit of SY::Molarity is SY::MOLAR:
|
199
|
-
MOLAR = Unit.standard of: Molarity,
|
199
|
+
MOLAR = Unit.standard of: Molarity, short: "M"
|
200
200
|
|
201
201
|
# Let us now note the #protect! directive at the line above defining
|
202
202
|
# SY::Molarity. Method #protect! prevents Molarity from understanding itself
|
data/lib/sy/dimension.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
# This class represents physical dimension of a metrological quantity.
|
4
4
|
#
|
@@ -46,7 +46,7 @@ class SY::Dimension
|
|
46
46
|
# Base dimension constructor. Base dimension symbol is expeced as argument.
|
47
47
|
#
|
48
48
|
def base symbol
|
49
|
-
raise
|
49
|
+
raise ArgumentError, "Unknown base dimension: #{symbol}" unless
|
50
50
|
SY::BASE_DIMENSIONS.base_symbols.include? symbol
|
51
51
|
return new( symbol => 1 )
|
52
52
|
end
|
@@ -76,7 +76,7 @@ class SY::Dimension
|
|
76
76
|
#
|
77
77
|
def [] ß
|
78
78
|
return send ß if SY::BASE_DIMENSIONS.letters.include? ß
|
79
|
-
raise
|
79
|
+
raise ArgumentError, "Unknown basic dimension: #{ß}"
|
80
80
|
end
|
81
81
|
|
82
82
|
#Two dimensions are equal, if their exponents are equal.
|
@@ -1,42 +1,35 @@
|
|
1
|
-
#
|
1
|
+
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
-
# This mixin
|
4
|
-
# symbols corresponding to metrological units defined in SY.
|
3
|
+
# This mixin provides ability to respond to SY unit symbol methods.
|
5
4
|
#
|
6
5
|
module SY::ExpressibleInUnits
|
7
|
-
|
6
|
+
RecursionError = Class.new StandardError
|
8
7
|
|
9
8
|
def method_missing ß, *args, &block
|
10
|
-
|
11
|
-
|
12
|
-
#
|
13
|
-
|
14
|
-
begin # prevent recurrent method_missing for the same symbol
|
15
|
-
anti_recursion_exec_with_token ß, :@SY_Units_mmiss do
|
9
|
+
return self if ß.to_s =~ /begin|end/ # 3rd party bug workaround
|
10
|
+
super if ß.to_s =~ /to_.+/ # dissmiss :to_..., esp. :to_ary
|
11
|
+
begin # prevent recurrent call of method_missing for the same symbol
|
12
|
+
anti_recursion_exec token: ß, var: :@SY_Units_mmiss do
|
16
13
|
puts "Method missing: '#{ß}'" if SY::DEBUG
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
self.class.module_eval write_unit_method( ß, prefixes, units, exps )
|
14
|
+
prefixes, units, exps = parse_unit_symbol ß
|
15
|
+
# Define the unit method on self.class:
|
16
|
+
ç.module_eval write_unit_method( ß, prefixes, units, exps )
|
21
17
|
end
|
22
|
-
rescue NameError =>
|
23
|
-
puts "NameError raised: #{
|
18
|
+
rescue NameError => err
|
19
|
+
puts "NameError raised: #{err}" if SY::DEBUG
|
24
20
|
super # give up
|
25
21
|
rescue SY::ExpressibleInUnits::RecursionError
|
26
22
|
super # give up
|
27
|
-
else # invoke the
|
23
|
+
else # actually invoke the method that we just defined
|
28
24
|
send ß, *args, &block
|
29
25
|
end
|
30
26
|
end
|
31
27
|
|
32
28
|
def respond_to_missing? ß, *args, &block
|
33
|
-
|
34
|
-
return false if
|
35
|
-
str == 'begin' || str == 'end' # bugs in 3rd party library
|
29
|
+
# dismiss :to_... methods and /begin|end/ (3rd party bug workaround)
|
30
|
+
return false if ß.to_s =~ /to_.+|begin|end/
|
36
31
|
begin
|
37
|
-
|
38
|
-
parse_unit_symbol( ß )
|
39
|
-
end
|
32
|
+
anti_recursion_exec token: ß, var: :@SY_Units_rmiss do parse_unit ß end
|
40
33
|
rescue NameError, SY::ExpressibleInUnits::RecursionError
|
41
34
|
false
|
42
35
|
else
|
@@ -53,9 +46,9 @@ module SY::ExpressibleInUnits
|
|
53
46
|
SY::Unit.parse_sps_using_all_prefixes( ß ) # rely on SY::Unit
|
54
47
|
end
|
55
48
|
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
49
|
+
# Takes method symbol, and three more array arguments, representing prefixes,
|
50
|
+
# unit symbols and exponents. Generates an appropriate unit method as a string.
|
51
|
+
# Arrays must be of equal length. (Note: 'ß' is 'symbol', 'ς' is 'string')
|
59
52
|
#
|
60
53
|
def write_unit_method ß, prefixes, units, exponents
|
61
54
|
known_units = SY::Unit.instances
|
@@ -70,16 +63,14 @@ module SY::ExpressibleInUnits
|
|
70
63
|
full_prefix == '' ? '' : ".#{full_prefix}"
|
71
64
|
end
|
72
65
|
# Return exponentiation string (suffix) or empty ς if not necessary.
|
73
|
-
exponentiation_ς = lambda do |
|
74
|
-
exponent == 1 ? '' : " ** #{exponent}"
|
75
|
-
end
|
66
|
+
exponentiation_ς = lambda do |exp| exp == 1 ? '' : " ** #{exp}" end
|
76
67
|
# Prepare prefix / unit / exponent triples for making factor strings:
|
77
68
|
triples = [ prefixes, units, exponents ].transpose
|
78
69
|
# A procedure for triple processing before use:
|
79
|
-
process_triple = lambda do |
|
80
|
-
[ find_unit.( unit_ς ).name.to_s.upcase,
|
81
|
-
prefix_method_ς.(
|
82
|
-
exponentiation_ς.(
|
70
|
+
process_triple = lambda do |pfx, unit_ς, exp|
|
71
|
+
[ find_unit.( unit_ς ).name.to_s.upcase,
|
72
|
+
prefix_method_ς.( pfx ),
|
73
|
+
exponentiation_ς.( exp ) ]
|
83
74
|
end
|
84
75
|
# Method skeleton:
|
85
76
|
if triples.size == 1 && triples.first[-1] == 1 then
|
@@ -99,8 +90,8 @@ module SY::ExpressibleInUnits
|
|
99
90
|
"end"
|
100
91
|
factors = [ "+( ::SY.Unit( :%s )%s )%s * self" %
|
101
92
|
process_triple.( *triples.shift ) ] +
|
102
|
-
triples.map do
|
103
|
-
"( ::SY.Unit( :%s )%s.relative ) )%s" % process_triple.(
|
93
|
+
triples.map do |triple|
|
94
|
+
"( ::SY.Unit( :%s )%s.relative ) )%s" % process_triple.( *triple )
|
104
95
|
end
|
105
96
|
# Multiply the factors toghether:
|
106
97
|
method_body = factors.join( " * \n " )
|
@@ -114,12 +105,10 @@ module SY::ExpressibleInUnits
|
|
114
105
|
# supplied block, and releases the token. The method guards against double
|
115
106
|
# execution for the same token, raising IllegalRecursionError in such case.
|
116
107
|
#
|
117
|
-
def
|
118
|
-
registry = self.class.instance_variable_get(
|
119
|
-
self.class.instance_variable_set(
|
120
|
-
if registry.include? token
|
121
|
-
raise SY::ExpressibleInUnits::RecursionError
|
122
|
-
end
|
108
|
+
def anti_recursion_exec( token: nil, var: :@SY_anti_recursion_exec )
|
109
|
+
registry = self.class.instance_variable_get( var ) ||
|
110
|
+
self.class.instance_variable_set( var, [] )
|
111
|
+
raise RecursionError if registry.include? token
|
123
112
|
begin
|
124
113
|
registry << token
|
125
114
|
yield if block_given?
|
@@ -1,11 +1,13 @@
|
|
1
|
-
#
|
1
|
+
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
# Here, fixed assets of the main module are set up.
|
4
4
|
#
|
5
5
|
module SY
|
6
|
-
#
|
7
|
-
#
|
8
|
-
|
6
|
+
QuantityError = Class.new StandardError # mixing incompatible quantities
|
7
|
+
DimensionError = Class.new StandardError # mixing incompatible dimensions
|
8
|
+
MagnitudeError = Class.new StandardError # creating impossible magnitude
|
9
|
+
|
10
|
+
BASE_DIMENSIONS = { # Basic physical dimensions.
|
9
11
|
L: :LENGTH,
|
10
12
|
M: :MASS,
|
11
13
|
Q: :ELECTRIC_CHARGE,
|
@@ -20,7 +22,8 @@ module SY
|
|
20
22
|
keys
|
21
23
|
end
|
22
24
|
|
23
|
-
# Base dimensions letters with prefixes.
|
25
|
+
# Base dimensions letters with prefixes. (Remark: I forgot what did I mean
|
26
|
+
# those prefixes for. Something important, I just forgot what.)
|
24
27
|
#
|
25
28
|
def prefixed_letters
|
26
29
|
[] # none for now
|
@@ -243,18 +246,6 @@ module SY
|
|
243
246
|
'["B", "s"], [1, -1]'
|
244
247
|
end
|
245
248
|
|
246
|
-
# Mainly for mixing incompatible quantities.
|
247
|
-
#
|
248
|
-
class QuantityError < StandardError; end
|
249
|
-
|
250
|
-
# Mainly for mixing incompatible dimensions.
|
251
|
-
#
|
252
|
-
class DimensionError < StandardError; end
|
253
|
-
|
254
|
-
# Mainly for negative or otherwise impossible physical amounts.
|
255
|
-
#
|
256
|
-
class MagnitudeError < StandardError; end
|
257
|
-
|
258
249
|
# Convenience dimension accessor.
|
259
250
|
#
|
260
251
|
def Dimension id=proc{ return ::SY::Dimension }.call
|
data/lib/sy/magnitude.rb
CHANGED
data/lib/sy/quantity.rb
CHANGED
@@ -446,10 +446,10 @@ class SY::Quantity
|
|
446
446
|
end
|
447
447
|
|
448
448
|
def explain_amount_of_standard_units
|
449
|
-
raise
|
450
|
-
":amount
|
451
|
-
"
|
452
|
-
"
|
453
|
-
"
|
449
|
+
raise TypeError, "For standard units, :amount is 1, by definition. When" +
|
450
|
+
":amount parameter is supplied to a standard unit constructor, its" +
|
451
|
+
"meaning is different: Using a magnitude of the same dimension, but" +
|
452
|
+
"different quantity, it establishes conversion relationship between" +
|
453
|
+
"the two quantities."
|
454
454
|
end
|
455
455
|
end # class SY::Quantity
|
data/lib/sy/version.rb
CHANGED
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: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- boris
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -38,7 +38,6 @@ files:
|
|
38
38
|
- Rakefile
|
39
39
|
- lib/sy.rb
|
40
40
|
- lib/sy/absolute_magnitude.rb
|
41
|
-
- lib/sy/abstract_algebra.rb
|
42
41
|
- lib/sy/composition.rb
|
43
42
|
- lib/sy/dimension.rb
|
44
43
|
- lib/sy/expressible_in_units.rb
|
data/lib/sy/abstract_algebra.rb
DELETED
@@ -1,102 +0,0 @@
|
|
1
|
-
#encoding: utf-8
|
2
|
-
|
3
|
-
# Adds abstract algebra concepts to Ruby.
|
4
|
-
#
|
5
|
-
module Algebra
|
6
|
-
# A Monoid requires:
|
7
|
-
#
|
8
|
-
# Closed and associative addition: #add method
|
9
|
-
# Additive identity element: #additive_identity
|
10
|
-
#
|
11
|
-
module Monoid
|
12
|
-
def + summand; add summand end
|
13
|
-
def zero; additive_identity end
|
14
|
-
end
|
15
|
-
|
16
|
-
# A group is a monoid with additive inverse.
|
17
|
-
#
|
18
|
-
# additive inversion: #additive_inverse
|
19
|
-
#
|
20
|
-
module Group
|
21
|
-
include Monoid
|
22
|
-
def -@; additive_inverse end
|
23
|
-
def - subtrahend; add subtrahend.additive_inverse end
|
24
|
-
end
|
25
|
-
|
26
|
-
# A group that fulfills the condition of commutativity
|
27
|
-
#
|
28
|
-
# ( a.add b == b.add a ).
|
29
|
-
#
|
30
|
-
module AbelianGroup
|
31
|
-
include Group
|
32
|
-
end
|
33
|
-
|
34
|
-
# A ring is a commutative group with multiplication.
|
35
|
-
#
|
36
|
-
# multiplication: #multiply (associative, distributive)
|
37
|
-
# multiplicative identity element: #multiplicative_identity
|
38
|
-
#
|
39
|
-
module Ring
|
40
|
-
include AbelianGroup
|
41
|
-
def * multiplicand; multiply multiplicand end
|
42
|
-
def one; multiplicative_identity end
|
43
|
-
end
|
44
|
-
|
45
|
-
# A field is a ring that can do division.
|
46
|
-
#
|
47
|
-
module Field
|
48
|
-
include Ring
|
49
|
-
def inverse; multiplicative_inverse end
|
50
|
-
def / divisor; multiply divisor.multiplicative_inverse end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Patching Integer with Algebra::Ring compliance methods.
|
55
|
-
#
|
56
|
-
class << Integer
|
57
|
-
def additive_identity; 0 end
|
58
|
-
alias zero additive_identity
|
59
|
-
def add( other ); self + other end
|
60
|
-
def additive_inverse; -self end
|
61
|
-
def multiply( other ); self * other end
|
62
|
-
def multiplicative_identity; 1 end
|
63
|
-
end
|
64
|
-
|
65
|
-
# Patching Float with Algebra::Field compliance methods.
|
66
|
-
#
|
67
|
-
class << Float
|
68
|
-
def additive_identity; 0.0 end
|
69
|
-
alias zero additive_identity
|
70
|
-
def add( other ); self + other end
|
71
|
-
def additive_inverse; -self end
|
72
|
-
def multiply( other ); self * other end
|
73
|
-
def multiplicative_identity; 1.0 end
|
74
|
-
alias one multiplicative_identity
|
75
|
-
def multiplicative_inverse; 1.0 / self end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Patching Rational with Algebra::Field compliance methods.
|
79
|
-
#
|
80
|
-
class << Rational
|
81
|
-
def additive_identity; Rational 0, 1 end
|
82
|
-
alias zero additive_identity
|
83
|
-
def add( other ); self + other end
|
84
|
-
def additive_inverse; -self end
|
85
|
-
def multiply( other ); self * other end
|
86
|
-
def multiplicative_identity; Rational 1, 1 end
|
87
|
-
alias one multiplicative_identity
|
88
|
-
def multiplicative_inverse; Rational( 1, 1 ) / self end
|
89
|
-
end
|
90
|
-
|
91
|
-
# Patching Complex with #zero method.
|
92
|
-
#
|
93
|
-
class << Complex
|
94
|
-
def additive_identity; Complex 0.0, 0.0 end
|
95
|
-
alias zero additive_identity
|
96
|
-
def add( other ); self + other end
|
97
|
-
def additive_inverse; -self end
|
98
|
-
def multiply( other ); self * other end
|
99
|
-
def multiplicative_identity; Complex 1, 0 end
|
100
|
-
alias one multiplicative_identity
|
101
|
-
def multiplicative_inverse; Complex( 1, 0 ) / self end
|
102
|
-
end
|