sy 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|