nrser 0.0.25 → 0.0.26
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/README.md +39 -11
- data/lib/nrser.rb +5 -1
- data/lib/nrser/array.rb +10 -53
- data/lib/nrser/enumerable.rb +21 -0
- data/lib/nrser/hash.rb +13 -476
- data/lib/nrser/hash/bury.rb +154 -0
- data/lib/nrser/hash/deep_merge.rb +57 -0
- data/lib/nrser/hash/except_keys.rb +42 -0
- data/lib/nrser/hash/guess_label_key_type.rb +37 -0
- data/lib/nrser/hash/slice_keys.rb +41 -0
- data/lib/nrser/hash/stringify_keys.rb +37 -0
- data/lib/nrser/hash/symbolize_keys.rb +41 -0
- data/lib/nrser/hash/transform_keys.rb +45 -0
- data/lib/nrser/merge_by.rb +26 -0
- data/lib/nrser/message.rb +125 -0
- data/lib/nrser/meta/props.rb +2 -2
- data/lib/nrser/meta/props/prop.rb +5 -2
- data/lib/nrser/object.rb +5 -0
- data/lib/nrser/object/as_array.rb +37 -0
- data/lib/nrser/object/as_hash.rb +101 -0
- data/lib/nrser/{truthy.rb → object/truthy.rb} +0 -0
- data/lib/nrser/proc.rb +132 -0
- data/lib/nrser/refinements.rb +1 -2
- data/lib/nrser/refinements/array.rb +94 -5
- data/lib/nrser/refinements/enumerable.rb +5 -0
- data/lib/nrser/refinements/hash.rb +43 -6
- data/lib/nrser/refinements/object.rb +22 -2
- data/lib/nrser/refinements/symbol.rb +12 -0
- data/lib/nrser/refinements/tree.rb +41 -0
- data/lib/nrser/rspex.rb +329 -0
- data/lib/nrser/string.rb +3 -0
- data/lib/nrser/string/looks_like.rb +51 -0
- data/lib/nrser/temp/where.rb +52 -0
- data/lib/nrser/tree.rb +86 -0
- data/lib/nrser/tree/leaves.rb +92 -0
- data/lib/nrser/tree/map_leaves.rb +63 -0
- data/lib/nrser/tree/transform.rb +30 -0
- data/lib/nrser/types.rb +9 -4
- data/lib/nrser/types/any.rb +1 -1
- data/lib/nrser/types/array.rb +167 -25
- data/lib/nrser/types/{hash.rb → hashes.rb} +19 -5
- data/lib/nrser/types/in.rb +47 -0
- data/lib/nrser/types/is_a.rb +2 -2
- data/lib/nrser/types/labels.rb +49 -0
- data/lib/nrser/types/numbers.rb +63 -27
- data/lib/nrser/types/pairs.rb +109 -0
- data/lib/nrser/types/responds.rb +2 -3
- data/lib/nrser/types/strings.rb +17 -18
- data/lib/nrser/types/symbols.rb +39 -0
- data/lib/nrser/types/trees.rb +93 -0
- data/lib/nrser/types/tuples.rb +116 -0
- data/lib/nrser/types/type.rb +26 -2
- data/lib/nrser/version.rb +1 -1
- data/spec/nrser/hash/{guess_name_type_spec.rb → guess_label_key_type_spec.rb} +3 -3
- data/spec/nrser/hash_spec.rb +0 -20
- data/spec/nrser/merge_by_spec.rb +73 -0
- data/spec/nrser/meta/props_spec.rb +136 -43
- data/spec/nrser/op/message_spec.rb +62 -0
- data/spec/nrser/refinements/array_spec.rb +36 -0
- data/spec/nrser/refinements/hash_spec.rb +34 -0
- data/spec/nrser/string/looks_like_spec.rb +31 -0
- data/spec/nrser/tree/each_branch_spec.rb +82 -0
- data/spec/nrser/tree/leaves_spec.rb +112 -0
- data/spec/nrser/tree/transform_spec.rb +165 -0
- data/spec/nrser/types/array_spec.rb +82 -0
- data/spec/nrser/types/attrs_spec.rb +4 -4
- data/spec/nrser/types/pairs_spec.rb +41 -0
- data/spec/nrser/types/paths_spec.rb +3 -3
- data/spec/nrser/types/strings_spec.rb +66 -0
- data/spec/nrser/types/symbols_spec.rb +38 -0
- data/spec/nrser/types/tuples_spec.rb +37 -0
- data/spec/nrser/types_spec.rb +0 -13
- data/spec/spec_helper.rb +71 -22
- metadata +58 -10
- data/lib/nrser/spex.rb +0 -68
- data/lib/nrser/types/symbol.rb +0 -23
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
require 'nrser/refinements/types'
|
7
|
+
using NRSER::Types
|
8
|
+
|
9
|
+
|
10
|
+
describe NRSER::Message, type: :class do
|
11
|
+
|
12
|
+
describe "#to_proc" do
|
13
|
+
|
14
|
+
describe_section "mapping an Enumerable using &message" do
|
15
|
+
subject { ->( message ) { enum.map &message } }
|
16
|
+
|
17
|
+
context_where enum: [ [], [1], [1, 2] ] do
|
18
|
+
|
19
|
+
describe_called_with NRSER::Message.new( :length ) do
|
20
|
+
it { is_expected.to eq [0, 1, 2] }
|
21
|
+
end # called with
|
22
|
+
|
23
|
+
describe_called_with NRSER::Message.new( :first ) do
|
24
|
+
it { is_expected.to eq [nil, 1, 1] }
|
25
|
+
end # called with :first
|
26
|
+
|
27
|
+
end # enum
|
28
|
+
|
29
|
+
end # mapping an Enumerable using &message
|
30
|
+
|
31
|
+
end # #to_proc
|
32
|
+
|
33
|
+
|
34
|
+
describe_section "Refinements" do
|
35
|
+
# ========================================================================
|
36
|
+
|
37
|
+
describe "Array#to_message" do
|
38
|
+
|
39
|
+
subject { array.to_message }
|
40
|
+
|
41
|
+
context_where array: [:fetch, :x] do
|
42
|
+
it {
|
43
|
+
is_expected.to be_a( NRSER::Message ).and have_attributes \
|
44
|
+
symbol: :fetch,
|
45
|
+
args: [:x],
|
46
|
+
block: nil
|
47
|
+
}
|
48
|
+
|
49
|
+
describe_sent_to x: 'ex', y: 'why?' do
|
50
|
+
it { is_expected.to eq 'ex' }
|
51
|
+
end # sent to x: 1, y: 2
|
52
|
+
|
53
|
+
end # array: [:fetch, :x]
|
54
|
+
|
55
|
+
end # Array#to_message
|
56
|
+
|
57
|
+
|
58
|
+
end # section Refinements
|
59
|
+
# ************************************************************************
|
60
|
+
|
61
|
+
|
62
|
+
end # NRSER::Message, type: :class
|
@@ -12,6 +12,7 @@ describe 'Refinement Array#map_values' do
|
|
12
12
|
end
|
13
13
|
end # Refinement Array#map_values
|
14
14
|
|
15
|
+
|
15
16
|
describe 'Refinement Array#find_bounded' do
|
16
17
|
it do
|
17
18
|
expect(
|
@@ -24,6 +25,7 @@ describe 'Refinement Array#find_bounded' do
|
|
24
25
|
end
|
25
26
|
end # Refinement Array#map_values
|
26
27
|
|
28
|
+
|
27
29
|
describe 'Refinement Array#find_only' do
|
28
30
|
it do
|
29
31
|
expect(
|
@@ -35,3 +37,37 @@ describe 'Refinement Array#find_only' do
|
|
35
37
|
}.to raise_error TypeError
|
36
38
|
end
|
37
39
|
end # Refinement Array#map_values
|
40
|
+
|
41
|
+
|
42
|
+
describe "Refinement Array#leaves" do
|
43
|
+
subject { [:a, :b, :c].leaves }
|
44
|
+
|
45
|
+
it { is_expected.to eq( {[0] => :a, [1] => :b, [2] => :c}) }
|
46
|
+
end # Refinement Array#leaves
|
47
|
+
|
48
|
+
|
49
|
+
describe "Refinement Array#each_branch" do
|
50
|
+
let( :abc_array ) { [:a, :b, :c] }
|
51
|
+
|
52
|
+
context "called with no block" do
|
53
|
+
subject { abc_array.each_branch }
|
54
|
+
|
55
|
+
it {
|
56
|
+
is_expected.to be_a( Enumerator ).
|
57
|
+
and have_attributes size: 3
|
58
|
+
}
|
59
|
+
end # called with no block
|
60
|
+
|
61
|
+
context "called with a block" do
|
62
|
+
subject {
|
63
|
+
result = {}
|
64
|
+
abc_array.each_branch { |key, value|
|
65
|
+
result[key] = value
|
66
|
+
}
|
67
|
+
result
|
68
|
+
}
|
69
|
+
|
70
|
+
it { is_expected.to eq(0 => :a, 1 => :b, 2 => :c) }
|
71
|
+
end # called with a block
|
72
|
+
|
73
|
+
end # Refinement Array#each_branch
|
@@ -41,3 +41,37 @@ describe 'Refinement Hash#find_only' do
|
|
41
41
|
}.to raise_error TypeError
|
42
42
|
end
|
43
43
|
end # Refinement Hash#map_values
|
44
|
+
|
45
|
+
|
46
|
+
describe "Refinement Hash#leaves" do
|
47
|
+
subject { {a: 1, b: 2, c: 3}.leaves }
|
48
|
+
|
49
|
+
it { is_expected.to eq( {[:a] => 1, [:b] => 2, [:c] => 3}) }
|
50
|
+
end # Refinement Hash#leaves
|
51
|
+
|
52
|
+
|
53
|
+
describe "Refinement Hash#each_branch" do
|
54
|
+
let( :abc_hash ) { {a: 1, b: 2, c: 3} }
|
55
|
+
|
56
|
+
context "called with no block" do
|
57
|
+
subject { abc_hash.each_branch }
|
58
|
+
|
59
|
+
it {
|
60
|
+
is_expected.to be_a( Enumerator ).
|
61
|
+
and have_attributes size: 3
|
62
|
+
}
|
63
|
+
end # called with no block
|
64
|
+
|
65
|
+
context "called with a block" do
|
66
|
+
subject {
|
67
|
+
result = {}
|
68
|
+
abc_hash.each_branch { |key, value|
|
69
|
+
result[key] = value * value
|
70
|
+
}
|
71
|
+
result
|
72
|
+
}
|
73
|
+
|
74
|
+
it { is_expected.to eq(a: 1, b: 4, c: 9) }
|
75
|
+
end # called with a block
|
76
|
+
|
77
|
+
end # Refinement Hash#each_branch
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
# NRSER.looks_like_json_array?
|
5
|
+
# ========================================================================
|
6
|
+
#
|
7
|
+
describe "NRSER.looks_like_json_array?" do
|
8
|
+
subject { NRSER.method :looks_like_json_array? }
|
9
|
+
|
10
|
+
multiline = <<-END
|
11
|
+
|
12
|
+
[
|
13
|
+
1,
|
14
|
+
2,
|
15
|
+
3
|
16
|
+
]
|
17
|
+
|
18
|
+
END
|
19
|
+
|
20
|
+
it_behaves_like "function",
|
21
|
+
mapping: {
|
22
|
+
'' => false,
|
23
|
+
'[]' => true,
|
24
|
+
'[1, 2, 3]' => true,
|
25
|
+
multiline => true,
|
26
|
+
}
|
27
|
+
|
28
|
+
|
29
|
+
end # NRSER.looks_like_json_array?
|
30
|
+
|
31
|
+
# ************************************************************************
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
describe "NRSER.each_branch" do
|
7
|
+
|
8
|
+
subject { NRSER.method :each_branch }
|
9
|
+
|
10
|
+
context "called without a block" do
|
11
|
+
context "called with arrays" do
|
12
|
+
when_called_with( [] ) {
|
13
|
+
it {
|
14
|
+
is_expected.to be_a( Enumerator ).
|
15
|
+
and have_attributes size: 0
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
when_called_with( [:x, :y, :z] ) {
|
20
|
+
it {
|
21
|
+
is_expected.to be_a( Enumerator ).
|
22
|
+
and have_attributes size: 3
|
23
|
+
}
|
24
|
+
}
|
25
|
+
end # called with arrays
|
26
|
+
|
27
|
+
context "called with hashes" do
|
28
|
+
when_called_with( {} ) {
|
29
|
+
it {
|
30
|
+
is_expected.to be_a( Enumerator ).
|
31
|
+
and have_attributes size: 0
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end # called with hashes
|
35
|
+
|
36
|
+
context "convert returned Enumerator to array" do
|
37
|
+
subject {
|
38
|
+
# CRASHES VM!!!
|
39
|
+
# ->( *args ) { super().call( *args ).to_a }
|
40
|
+
->( *args ) { NRSER.each_branch( *args ).to_a }
|
41
|
+
}
|
42
|
+
|
43
|
+
it_behaves_like 'function',
|
44
|
+
mapping: {
|
45
|
+
[ {x: 'ex', y: 'why?', z: 'zee!'} ] => [
|
46
|
+
[:x, 'ex'],
|
47
|
+
[:y, 'why?'],
|
48
|
+
[:z, 'zee!'],
|
49
|
+
],
|
50
|
+
|
51
|
+
[ [:x, :y, :z] ] => [
|
52
|
+
[0, :x],
|
53
|
+
[1, :y],
|
54
|
+
[2, :z],
|
55
|
+
]
|
56
|
+
}
|
57
|
+
end # convert Enumerator to array
|
58
|
+
end # called without a block
|
59
|
+
|
60
|
+
context "called with a block" do
|
61
|
+
|
62
|
+
context "called with arrays" do
|
63
|
+
|
64
|
+
subject {
|
65
|
+
input = [:x, :y, :z]
|
66
|
+
result = {}
|
67
|
+
super().call( input ) { |index, value|
|
68
|
+
result[index] = value
|
69
|
+
}
|
70
|
+
result
|
71
|
+
}
|
72
|
+
|
73
|
+
it {
|
74
|
+
is_expected.to eq(0 => :x, 1 => :y, 2 => :z)
|
75
|
+
}
|
76
|
+
|
77
|
+
end # called with arrays
|
78
|
+
|
79
|
+
end # called with a block
|
80
|
+
|
81
|
+
end # NRSER.each_branch
|
82
|
+
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "NRSER.leaves" do
|
4
|
+
subject { NRSER.method :leaves }
|
5
|
+
|
6
|
+
it_behaves_like "function",
|
7
|
+
mapping: {
|
8
|
+
# flat hash
|
9
|
+
[{a: 1, b: 2}] => {[:a] => 1, [:b] => 2},
|
10
|
+
|
11
|
+
# flat array
|
12
|
+
[ [:a, :b, :c] ] => {
|
13
|
+
[0] => :a,
|
14
|
+
[1] => :b,
|
15
|
+
[2] => :c,
|
16
|
+
},
|
17
|
+
|
18
|
+
# Nested, all hashes
|
19
|
+
[{
|
20
|
+
a: {
|
21
|
+
x: 'ex',
|
22
|
+
y: {
|
23
|
+
z: 'zee'
|
24
|
+
}
|
25
|
+
},
|
26
|
+
b: 'bee',
|
27
|
+
}] => {
|
28
|
+
[:a, :x] => 'ex',
|
29
|
+
[:a, :y, :z] => 'zee',
|
30
|
+
[:b] => 'bee',
|
31
|
+
},
|
32
|
+
|
33
|
+
# Mixed arrays and hashes
|
34
|
+
[{
|
35
|
+
1 => {
|
36
|
+
name: 'Neil',
|
37
|
+
likes: ['tacos', 'cats'],
|
38
|
+
},
|
39
|
+
|
40
|
+
2 => {
|
41
|
+
name: 'Mica',
|
42
|
+
likes: ['cats', 'cookies'],
|
43
|
+
},
|
44
|
+
}] => {
|
45
|
+
[1, :name] => 'Neil',
|
46
|
+
[1, :likes, 0] => 'tacos',
|
47
|
+
[1, :likes, 1] => 'cats',
|
48
|
+
[2, :name] => 'Mica',
|
49
|
+
[2, :likes, 0] => 'cats',
|
50
|
+
[2, :likes, 1] => 'cookies',
|
51
|
+
},
|
52
|
+
|
53
|
+
# Sets should be considered leaves
|
54
|
+
[{
|
55
|
+
neil: {
|
56
|
+
name: 'Neil',
|
57
|
+
likes: Set['tacos', 'cats'],
|
58
|
+
},
|
59
|
+
}] => {
|
60
|
+
[:neil, :name] => 'Neil',
|
61
|
+
[:neil, :likes] => Set['tacos', 'cats'],
|
62
|
+
},
|
63
|
+
} # mapping
|
64
|
+
|
65
|
+
end # NRSER.leaves
|
66
|
+
|
67
|
+
describe "NRSER.map_leaves" do
|
68
|
+
let( :source ) {
|
69
|
+
{
|
70
|
+
1 => {
|
71
|
+
name: 'Neil',
|
72
|
+
likes: ['tacos', 'cats'],
|
73
|
+
},
|
74
|
+
|
75
|
+
2 => {
|
76
|
+
name: 'Mica',
|
77
|
+
likes: ['cats', 'cookies'],
|
78
|
+
},
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
subject {
|
83
|
+
NRSER.map_leaves( source ) { |key_path, value|
|
84
|
+
case value
|
85
|
+
when 'tacos'
|
86
|
+
'tamales'
|
87
|
+
when 'cats'
|
88
|
+
'bats'
|
89
|
+
when 'cookies'
|
90
|
+
'wookies'
|
91
|
+
else
|
92
|
+
value
|
93
|
+
end
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
it {
|
98
|
+
is_expected.to eq({
|
99
|
+
1 => {
|
100
|
+
name: 'Neil',
|
101
|
+
likes: ['tamales', 'bats'],
|
102
|
+
},
|
103
|
+
|
104
|
+
2 => {
|
105
|
+
name: 'Mica',
|
106
|
+
likes: ['bats', 'wookies'],
|
107
|
+
},
|
108
|
+
})
|
109
|
+
}
|
110
|
+
|
111
|
+
end # NRSER.map_leaves
|
112
|
+
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'nrser/refinements'
|
4
|
+
using NRSER
|
5
|
+
|
6
|
+
describe "NRSER.transform" do
|
7
|
+
subject { NRSER.transform tree, source }
|
8
|
+
|
9
|
+
describe_section "Simple Examples" do
|
10
|
+
# ========================================================================
|
11
|
+
|
12
|
+
describe "value swap in {x: 'ex', y: 'why?'}" do
|
13
|
+
|
14
|
+
let( :tree ) {
|
15
|
+
{
|
16
|
+
x: :y.retriever,
|
17
|
+
y: :x.retriever,
|
18
|
+
}
|
19
|
+
} # let :tree
|
20
|
+
|
21
|
+
let( :source ) {
|
22
|
+
{
|
23
|
+
x: 'ex',
|
24
|
+
y: 'why?'
|
25
|
+
}
|
26
|
+
} # let :source
|
27
|
+
|
28
|
+
it { is_expected.to eq x: 'why?', y: 'ex' }
|
29
|
+
|
30
|
+
end # value swap in {x: 'ex', y: 'why?'}
|
31
|
+
|
32
|
+
|
33
|
+
describe "transform in key" do
|
34
|
+
|
35
|
+
let :tree do
|
36
|
+
{
|
37
|
+
users: {
|
38
|
+
{ id: :id.retriever } => {
|
39
|
+
name: :name.retriever,
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
let :source do
|
46
|
+
{
|
47
|
+
id: 123,
|
48
|
+
name: "Mr. Cat",
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
it do
|
53
|
+
is_expected.to eq \
|
54
|
+
users: {
|
55
|
+
{ id: 123 } => {
|
56
|
+
name: "Mr. Cat",
|
57
|
+
}
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
end # transform in key
|
62
|
+
|
63
|
+
# TODO doesn't work yet... prob wants a general {NRSER#map_branches} or
|
64
|
+
# something that converts the map result into a Hash only if the
|
65
|
+
# tree was hash-like.
|
66
|
+
#
|
67
|
+
# describe "arrays in tree" do
|
68
|
+
# let :tree do
|
69
|
+
# {
|
70
|
+
# list: [
|
71
|
+
# { name: :name.rtvr },
|
72
|
+
# { age: :age.rtvr },
|
73
|
+
# ]
|
74
|
+
# }
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# let :source do
|
78
|
+
# {
|
79
|
+
# name: 'Mr. Cat',
|
80
|
+
# age: 2,
|
81
|
+
# }
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# it do
|
85
|
+
# is_expected.to eq \
|
86
|
+
# list: [
|
87
|
+
# { name: 'Mr. Cat' },
|
88
|
+
# { age: 2 },
|
89
|
+
# ]
|
90
|
+
# end
|
91
|
+
# end # arrays in tree
|
92
|
+
|
93
|
+
|
94
|
+
end # section simple examples
|
95
|
+
# ************************************************************************
|
96
|
+
|
97
|
+
|
98
|
+
describe_section "Real-World Examples" do
|
99
|
+
# ========================================================================
|
100
|
+
|
101
|
+
describe "Address" do
|
102
|
+
|
103
|
+
let :contact do
|
104
|
+
OpenStruct.new id: 123
|
105
|
+
end
|
106
|
+
|
107
|
+
let :address do
|
108
|
+
OpenStruct.new \
|
109
|
+
id: 987,
|
110
|
+
parent: contact,
|
111
|
+
address: "东城区",
|
112
|
+
street2: "民安小区",
|
113
|
+
city: "北京市",
|
114
|
+
state: "北京",
|
115
|
+
zip: "100010"
|
116
|
+
end
|
117
|
+
|
118
|
+
let :source do
|
119
|
+
address
|
120
|
+
end
|
121
|
+
|
122
|
+
let :tree do
|
123
|
+
{
|
124
|
+
users: {
|
125
|
+
{ contact_id: [ :parent, :id ].chainer } => {
|
126
|
+
addresses: {
|
127
|
+
{
|
128
|
+
address_id: [ :id ].sender } => {
|
129
|
+
district: :address.retriever,
|
130
|
+
line_1: :street2.retriever,
|
131
|
+
city: :city.retriever,
|
132
|
+
province: :state.retriever,
|
133
|
+
post_code: :zip.retriever,
|
134
|
+
}
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
it do
|
142
|
+
is_expected.to eq \
|
143
|
+
users: {
|
144
|
+
{ contact_id: 123 } => {
|
145
|
+
addresses: {
|
146
|
+
{ address_id: 987 } => {
|
147
|
+
district: "东城区",
|
148
|
+
line_1: "民安小区",
|
149
|
+
city: "北京市",
|
150
|
+
province: "北京",
|
151
|
+
post_code: "100010",
|
152
|
+
}
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
end # Address
|
159
|
+
|
160
|
+
end # section Real-World Examples
|
161
|
+
# ************************************************************************
|
162
|
+
|
163
|
+
|
164
|
+
end # NRSER.transform
|
165
|
+
|