general 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,93 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require_relative "gpartial"
18
+
19
+ # General is a templating system in ruby
20
+ #
21
+ # Author: Anshul Kharbanda
22
+ # Created: 3 - 4 - 2016
23
+ module General
24
+ # Represents a plain text partial in a GTemplate
25
+ #
26
+ # Author: Anshul Kharbanda
27
+ # Created: 7 - 1 - 2016
28
+ class GText < GPartial
29
+ # Regular expression that matches text partials
30
+ REGEX = /\A[^@]+?(?=(@|\\@|\z))/m
31
+
32
+ # The partial name of a text
33
+ PTNAME = :gpartialstring
34
+
35
+ # Initializes the GText with the given match
36
+ #
37
+ # Parameter: match - the match object of the GText
38
+ def initialize(match)
39
+ super name: PTNAME
40
+ @text = match.to_s
41
+ end
42
+
43
+ # Returns the text
44
+ #
45
+ # Parameter: data - the data to apply to the partial
46
+ #
47
+ # Returns: the text
48
+ def apply(data); @text; end
49
+
50
+ # Returns the text as a string
51
+ #
52
+ # Parameter: first - true if this partial is the first of it's kind in a GTemplate
53
+ #
54
+ # Returns: the text as a string
55
+ def string(first=true); @text.inspect[1...-1]; end
56
+
57
+ # Returns the text as a regex
58
+ #
59
+ # Parameter: first - true if this partial is the first of it's kind in a GTemplate
60
+ #
61
+ # Returns: the text as a regex
62
+ def regex(first=true); @text.inspect[1...-1].gsub(/[\.\+\-\*]/) { |s| "\\#{s}" }; end
63
+ end
64
+
65
+ # Represents a special character in a GTemplate
66
+ #
67
+ # Author: Anshul Kharbanda
68
+ # Created: 7 - 29 - 2016
69
+ class GSpecial < GText
70
+ # Regular expression that matches special partials
71
+ REGEX = /\A@(?<key>\w+)\;/
72
+
73
+ # Special character information
74
+ SPECIALS = {
75
+ at: "@", pd: "#",
76
+ lt: "<", gt: ">",
77
+ op: "(", cp: ")",
78
+ ob: "[", cb: "]",
79
+ oc: "{", cc: "}",
80
+ ms: "-", ps: "+",
81
+ st: "*", pc: "%",
82
+ bs: "\\", fs: "/",
83
+ dl: "$",
84
+ }
85
+
86
+ # Initializes the GSpecial with the given match
87
+ #
88
+ # Parameter: match - the match object of the GSpecial
89
+ def initialize(match)
90
+ super SPECIALS[match[:key].to_sym]
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,71 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require_relative "gpartial"
18
+
19
+ # General is a templating system in ruby
20
+ #
21
+ # Author: Anshul Kharbanda
22
+ # Created: 3 - 4 - 2016
23
+ module General
24
+ # Represents an timeformat placeholder partial in a GTimeFormat
25
+ #
26
+ # Author: Anshul Kharbanda
27
+ # Created: 7 - 1 - 2016
28
+ class GTimeFormatPlaceholder < GPartial
29
+ # Regular expression that matches timeformat placeholders
30
+ REGEX = /@(?<name>[A-Z]+)/
31
+
32
+ # Returns the value of the timeformat placeholder in the given time value
33
+ # formatted according to the time format name
34
+ #
35
+ # Parameter: value - the time value being applied
36
+ #
37
+ # Return: the value of the timeformat placeholder in the given time value
38
+ # formatted according to the time format name
39
+ def apply value
40
+ map = name_map(value).to_s
41
+ return is_justify? ? map.rjust(@name.length, '0') : map
42
+ end
43
+
44
+ # Returns true if the timeformat placeholder is a justifiable name
45
+ #
46
+ # Return: true if the timeformat placeholder is a justifiable name
47
+ def is_justify?; "HIMS".include? @name[0]; end
48
+
49
+ # Returns the string representation of the timeformat placeholder
50
+ #
51
+ # Return: the string representation of the timeformat placeholder
52
+ def to_s; "@#{@name}"; end
53
+
54
+ private
55
+
56
+ # Returns the value modified according to the raw timeformat name
57
+ #
58
+ # Parameter: value - the time value being applied
59
+ #
60
+ # Return: the value modified according to the raw timeformat name
61
+ def name_map value
62
+ case @name[0]
63
+ when "H" then (value / 3600)
64
+ when "I" then (value / 3600 % 12 + 1)
65
+ when "M" then (value % 3600 / 60)
66
+ when "S" then (value % 3600 % 60)
67
+ when "A" then (value / 3600 > 11 ? 'PM' : 'AM')
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,55 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ # General is a templating system in ruby
18
+ #
19
+ # Author: Anshul Kharbanda
20
+ # Created: 3 - 4 - 2016
21
+ module General
22
+ # The base class for General template objects
23
+ # Implementing objects must define a :apply method
24
+ # Which applies the GTemplate to an object
25
+ #
26
+ # Author: Anshul Kharbanda
27
+ # Created: 7 - 30 - 2016
28
+ class GBaseTemplate
29
+ # Initializes the GBaseTemplate with the given string
30
+ #
31
+ # Parameter: string - the string to initialize the GBaseTemplate with
32
+ def initialize string
33
+ @partials = []
34
+ end
35
+
36
+ # Applies the given data to the template and returns the generated string
37
+ #
38
+ # Parameter: data - the data to be applied (as a hash. merges with defaults)
39
+ #
40
+ # Return: string of the template with the given data applied
41
+ def apply(data={}); @partials.collect { |partial| partial.apply(data) }.join; end
42
+
43
+ # Applies each data structure in the array independently to the template
44
+ # and returns an array of the generated strings
45
+ #
46
+ # Parameter: array - the array of data to be applied
47
+ # (each data hash will be merged with defaults)
48
+ #
49
+ # Return: array of strings generated from the template with the given
50
+ # data applied
51
+ def apply_all array
52
+ array.collect { |data| apply(data) }
53
+ end
54
+ end
55
+ end
@@ -50,8 +50,7 @@ module General
50
50
  @source = source
51
51
  end
52
52
 
53
- # Writes the template with the given
54
- # data applied to the target stream
53
+ # Writes the template with the given data applied to the target stream
55
54
  #
56
55
  # Parameter: ios - if String, is the name of the file to write to
57
56
  # if IO, is the stream to write to
@@ -0,0 +1,103 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require_relative "gbasetemplate"
18
+ require_relative "../gpartials/gtext"
19
+ require_relative "../gpartials/gplaceholder"
20
+
21
+ # General is a templating system in ruby
22
+ #
23
+ # Author: Anshul Kharbanda
24
+ # Created: 3 - 4 - 2016
25
+ module General
26
+ # Implements the general templating system for strings
27
+ #
28
+ # Author: Anshul Kharbanda
29
+ # Created: 3 - 4 - 2016
30
+ class GTemplate < GBaseTemplate
31
+ # Creates a GTemplate with the given template string
32
+ #
33
+ # Parameter: string - the string being converted to a template
34
+ def initialize string
35
+ super(string)
36
+ @defaults = General::GDotHash.new
37
+
38
+ # The string gets split into partials by placeholder and array template
39
+ loop do
40
+ if match = General::GText::REGEX.match(string)
41
+ @partials << General::GText.new(match)
42
+ elsif match = General::GSpecial::REGEX.match(string)
43
+ @partials << General::GSpecial.new(match)
44
+ elsif match = General::GArrayPlaceholder::REGEX.match(string)
45
+ @partials << General::GArrayPlaceholder.new(match)
46
+ elsif match = General::GPlaceholder::REGEX.match(string)
47
+ @partials << General::GPlaceholder.new(match, @defaults)
48
+ else
49
+ return
50
+ end
51
+ string = string[match.end(0)..-1]
52
+ end
53
+ end
54
+
55
+ # Returns a string representation of the string
56
+ #
57
+ # Return: a string representation of the string
58
+ def to_s
59
+ first = Hash.new(true); str = ""
60
+ @partials.each do |part|
61
+ str += part.string(first[part.name])
62
+ first[part.name] &&= false
63
+ end
64
+ return str
65
+ end
66
+
67
+ # Returns the string as a regex
68
+ #
69
+ # Returns: the string as a regex
70
+ def regex sub=false
71
+ first = Hash.new(true); str = ""
72
+ @partials.each do |part|
73
+ str += part.regex(first[part.name]);
74
+ first[part.name] &&= false
75
+ end
76
+ return sub ? str : Regexp.new("\\A" + str + "\\z")
77
+ end
78
+
79
+ # Matches the given string against the template and returns the
80
+ # collected information. Returns nil if the given string does
81
+ # not match.
82
+ #
83
+ # If a block is given, it will be run with the generated hash
84
+ # if the string matches. Alias for:
85
+ #
86
+ # if m = template.match(string)
87
+ # # Run block
88
+ # end
89
+ #
90
+ # Parameter: string the string to match
91
+ #
92
+ # Return: Information matched from the string or nil
93
+ def match string
94
+ regex.match(string) do |match|
95
+ hash = match.names.collect { |name|
96
+ [name.to_sym, match[name.to_sym]]
97
+ }.to_h
98
+ yield hash if block_given?
99
+ return hash
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,62 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require_relative "gbasetemplate"
18
+ require_relative "../gpartials/gtext"
19
+ require_relative "../gpartials/gtimeformatplaceholder"
20
+
21
+ # General is a templating system in ruby
22
+ #
23
+ # Author: Anshul Kharbanda
24
+ # Created: 3 - 4 - 2016
25
+ module General
26
+ # A special template used for formatting time strings
27
+ #
28
+ # Author: Anshul Kharbanda
29
+ # Created: 7 - 2 - 2016
30
+ class GTimeFormat < GBaseTemplate
31
+ # Initialize the GTimeFormat with the given string
32
+ #
33
+ # Parameter: string - the template string
34
+ def initialize string
35
+ super string
36
+
37
+ loop do
38
+ if match = General::GText::REGEX.match(string)
39
+ @partials << General::GText.new(match)
40
+ elsif match = General::GTimeFormatPlaceholder::REGEX.match(string)
41
+ @partials << General::GTimeFormatPlaceholder.new(match)
42
+ else
43
+ return
44
+ end
45
+ string = string[match.end(0)..-1]
46
+ end
47
+ end
48
+
49
+ # Applies the given integer value to the template and returns the generated string
50
+ #
51
+ # Parameter: value - the value to be applied (as a hash. merges with defaults)
52
+ #
53
+ # Return: string of the template with the given value applied
54
+ def apply value
55
+ if value.is_a? Integer
56
+ super value
57
+ else
58
+ raise TypeError.new "Expected Integer, got: #{value.class}"
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,163 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require_relative "spec_require"
18
+
19
+ # Describe General::GArrayPlaceholder
20
+ #
21
+ # Represents an array placeholder partial in a GTemplate
22
+ #
23
+ # Author: Anshul Kharbanda
24
+ # Created: 7 - 1 - 2016
25
+ describe General::GArrayPlaceholder do
26
+ before :all do
27
+ # -----------DATA-----------
28
+
29
+ @arrayname1 = :arg
30
+ @hash = {
31
+ arg: [
32
+ { subarg: "Eeeeyyy" },
33
+ { subarg: "Oyyyeee" },
34
+ { subarg: "Aaayyyy" }
35
+ ]
36
+ }
37
+
38
+ @text = "Subarg: @(subarg)"
39
+ @regex = "Subarg: (?<subarg>.*)"
40
+ @delim = "\n"
41
+
42
+ # ---------------------------OUTPUT---------------------------
43
+
44
+ @out1 = @hash[@arrayname1]
45
+ .collect{|e| "Subarg: #{e[:subarg]}"}
46
+ .join(General::GArrayPlaceholder::DEFAULT_DELIMETER)
47
+ @out2 = @hash[@arrayname1]
48
+ .collect{|e| "Subarg: #{e[:subarg]}"}
49
+ .join(@delim)
50
+
51
+ # ------------------------------------------PARTIALS------------------------------------------
52
+
53
+ @partial1 = General::GArrayPlaceholder.new name: @arrayname1, text: @text
54
+ @partial2 = General::GArrayPlaceholder.new name: @arrayname1, text: @text, delimeter: @delim
55
+
56
+ # -------------------------------------------STRING-------------------------------------------
57
+
58
+ @string1 = "@[#{@arrayname1}] #{@text} @[ ]"
59
+ @string2 = "@[#{@arrayname1}] #{@text} @[\\n]"
60
+
61
+ # -------------------------------------------REGEX--------------------------------------------
62
+
63
+ @regex1 = "(?<#{@arrayname1}>(#{@regex}( )?)+)"
64
+ @regex2 = "(?<#{@arrayname1}>(#{@regex}(\\n)?)+)"
65
+ end
66
+
67
+ # Describe General::GArrayPlaceholder::new
68
+ #
69
+ # Initializes the GPlaceholder with the given match
70
+ #
71
+ # Parameter: match - the match data from the string being parsed
72
+ describe '::new' do
73
+ context 'with the given name and text' do
74
+ it 'creates a new GArrayPlaceholder with the given name and text' do
75
+ expect(@partial1).to be_an_instance_of General::GArrayPlaceholder
76
+ end
77
+ end
78
+
79
+ context 'with the given name, text, and delimeter' do
80
+ it 'creates a new GArrayPlaceholder with the given name and text and delimeter' do
81
+ expect(@partial1).to be_an_instance_of General::GArrayPlaceholder
82
+ end
83
+ end
84
+ end
85
+
86
+ # Describe General::GArrayPlaceholder#apply
87
+ #
88
+ # Returns the value of the array placeholder in the given data
89
+ # formatted by the given GArrayPlaceholder and joined by the given delimeter
90
+ #
91
+ # Parameter: data - the data being applied
92
+ #
93
+ # Return: the value of the array placeholder in the given data
94
+ # formatted by the given GArrayPlaceholder and joined by the given delimeter
95
+ describe '#apply' do
96
+ it 'applies the given data array formatted according to the given GArrayPlaceholder and joined by the delimeter' do
97
+ expect(@partial1.apply @hash).to eql @out1
98
+ expect(@partial2.apply @hash).to eql @out2
99
+ end
100
+ end
101
+
102
+ # Describe General::GArrayPlaceholder#string
103
+ #
104
+ # Returns the string representation of the GArrayPlaceholder
105
+ #
106
+ # Parameter: first - true if the GArrayPlaceholder is the first of it's time
107
+ #
108
+ # Returns: the string representation of the GArrayPlaceholder
109
+ describe '#string' do
110
+ context 'with no first argument is given' do
111
+ it 'returns the string of the GArrayPlaceholder' do
112
+ expect(@partial1.string).to eql @string1
113
+ expect(@partial2.string).to eql @string2
114
+ end
115
+ end
116
+
117
+ context 'with first argument is given' do
118
+ context 'when first is true' do
119
+ it 'returns the string of the GArrayPlaceholder' do
120
+ expect(@partial1.string true).to eql @string1
121
+ expect(@partial2.string true).to eql @string2
122
+ end
123
+ end
124
+
125
+ context 'when first is false' do
126
+ it 'returns the string of the GArrayPlaceholder' do
127
+ expect(@partial1.string false).to eql @string1
128
+ expect(@partial2.string false).to eql @string2
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ # Describe General::GArrayPlaceholder#regex
135
+ #
136
+ # Throws TypeError
137
+ #
138
+ # Parameter: first - true if the placeholder is the first of it's kind
139
+ describe '#regex' do
140
+ context 'with no first argument is given' do
141
+ it 'returns the regex of the GArrayPlaceholder' do
142
+ expect { @partial1.regex }.to raise_error TypeError
143
+ expect { @partial2.regex }.to raise_error TypeError
144
+ end
145
+ end
146
+
147
+ context 'with first argument is given' do
148
+ context 'when first is true' do
149
+ it 'returns the regex of the GArrayPlaceholder' do
150
+ expect { @partial1.regex true }.to raise_error TypeError
151
+ expect { @partial2.regex true }.to raise_error TypeError
152
+ end
153
+ end
154
+
155
+ context 'when first is false' do
156
+ it 'returns the regex of the GArrayPlaceholder' do
157
+ expect { @partial1.regex false }.to raise_error TypeError
158
+ expect { @partial2.regex false }.to raise_error TypeError
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,87 @@
1
+ # General is a templating system in ruby
2
+ # Copyright (C) 2016 Anshul Kharbanda
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require_relative "spec_require"
18
+
19
+ # Describing General::GDotHash
20
+ #
21
+ # Wrapper for hash objects which implements dot notation
22
+ #
23
+ # Author: Anshul Kharbanda
24
+ # Created: 9 - 27 - 2016
25
+ describe General::GDotHash do
26
+ before :all do
27
+ @hash = {name: {first: "Joe", last: "Schmoe"}}
28
+ @key1 = :"name.first"
29
+ @key2 = :"name.middle"
30
+ @value1 = @hash[:name][:first]
31
+ @newvalue1 = "Doe"
32
+ @newvalue2 = "Bobo"
33
+ @gdothash = General::GDotHash.new @hash
34
+ end
35
+
36
+ # Describing General::GDotHash::new
37
+ #
38
+ # Initializes the given GDotHash with the given hash
39
+ #
40
+ # Parameter: hash - the hash being manipulated
41
+ describe "::new" do
42
+ it 'creates a new GDotHash with the given hash' do
43
+ expect(@gdothash).to be_an_instance_of General::GDotHash
44
+ expect(@gdothash.instance_variable_get(:@hash)).to eql @hash
45
+ end
46
+ end
47
+
48
+ # Returns the string representation of the hash
49
+ #
50
+ # Return: the string representation of the hash
51
+ describe '#to_s' do
52
+ it 'returns the string representation of the given GDotHash' do
53
+ expect(@gdothash.to_s).to eql @hash.to_s
54
+ end
55
+ end
56
+
57
+ # Gets the value at the given key
58
+ #
59
+ # Parameter: key - the key to return
60
+ #
61
+ # Return: the value at the given key
62
+ describe '#[]' do
63
+ it 'returns the value addressed by the given dot notation key' do
64
+ expect(@gdothash[@key1]).to eql @value1
65
+ end
66
+ end
67
+
68
+ # Sets the given key to the given value
69
+ #
70
+ # Parameter: key - the key to set
71
+ # Parameter: value - the value to set
72
+ describe '#[]=' do
73
+ context 'if given position exists' do
74
+ it 'sets the position addressed by the given dot notation key to the given value' do
75
+ expect { @gdothash[@key1] = @newvalue1 }.not_to raise_error
76
+ expect(@gdothash[@key1]).to eql @newvalue1
77
+ end
78
+ end
79
+
80
+ context 'if given position does not exist' do
81
+ it 'creates position addressed by the given dot notation key in the given hash and sets it to the given value' do
82
+ expect { @gdothash[@key2] = @newvalue2 }.not_to raise_error
83
+ expect(@gdothash[@key2]).to eql @newvalue2
84
+ end
85
+ end
86
+ end
87
+ end