coltrane 2.1.5 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,58 +7,47 @@ module Coltrane
7
7
  attr_reader :intervals
8
8
 
9
9
  def_delegators :@intervals, :map, :each, :[], :size,
10
- :reduce, :delete, :reject!, :delete_if
11
-
12
- IntervalClass.all_full_names.each do |full_name|
13
- define_method "has_#{full_name.underscore}?" do
14
- !!(intervals.detect { |i| i.public_send("#{full_name.underscore}?") })
15
- end
16
- end
17
-
18
- (1..15).each do |i|
19
- # defines methods like :fifth, :third, eleventh:
20
- define_method i.interval_name.underscore do
21
- priority = send("#{i.interval_name.underscore}!")
22
- return priority unless priority.nil?
23
- @intervals.each do |ix|
24
- ix.full_names.detect do |ixx|
25
- return ixx if ixx.match?(/#{i.interval_name}/)
26
- end
10
+ :reduce, :delete, :reject!, :delete_if, :detect, :to_a
11
+
12
+ def initialize(*intervals, notes: nil, relative_intervals: nil)
13
+ if intervals.any?
14
+ @intervals = if intervals.first.is_a?(Interval)
15
+ intervals
16
+ else
17
+ intervals.map { |i| Interval[i] }
27
18
  end
28
- nil
29
- end
30
-
31
- define_method "#{i.interval_name.underscore}!" do
32
- @intervals.each do |ix|
33
- ix.full_names.detect do |ixx|
34
- next if ixx.match?(/Diminished|Augmented/)
35
- return ixx if ixx.match? /#{i.interval_name}/
36
- end
37
- end
38
- nil
39
- end
40
-
41
- # defines methods like :has_fifth?, :has_third?, has_eleventh?:
42
- define_method "has_#{i.interval_name.underscore}?" do
43
- !!@intervals.detect { |ix| ix.full_name.match(/#{i.interval_name}/) }
44
- end
45
- end
46
19
 
47
- def initialize(notes: nil, intervals: nil, distances: nil)
48
- if notes
20
+ elsif notes
49
21
  notes = NoteSet[*notes] if notes.is_a?(Array)
50
22
  @intervals = intervals_from_notes(notes)
51
- elsif intervals
52
- @intervals = intervals.map { |i| IntervalClass[i] }
53
- elsif distances
54
- @distances = distances
55
- @intervals = intervals_from_distances(distances)
23
+ elsif relative_intervals
24
+ @relative_intervals = relative_intervals
25
+ @intervals = intervals_from_relative_intervals(relative_intervals)
56
26
  else
57
- raise 'Provide: [notes:] || [intervals:] || [distances:]'
27
+ raise WrongKeywordsError,
28
+ 'Provide: [notes:] || [intervals:] || [relative_intervals:]'
58
29
  end
59
30
  end
60
31
 
61
- def distances
32
+ Interval.all_including_compound_and_altered.each do |interval|
33
+ # Creates methods such as major_third, returning it if it finds
34
+ define_method(interval.full_name.underscore.to_s) { find(interval) }
35
+ # Creates methods such as has_major_third?, returning a boolean
36
+ define_method("has_#{interval.full_name.underscore}?") { has?(interval) }
37
+ end
38
+
39
+ Interval.distances_names.map(&:underscore).each_with_index do |distance, i|
40
+ # Creates methods such as has_third?, returning a boolean
41
+ define_method("has_#{distance}?") { !!find_by_distance(i + 1) }
42
+ # Creates methods such third, returning any third it finds
43
+ define_method(distance.to_s) { find_by_distance(i + 1) }
44
+ # Creates methods such third!, returning thirds that arent aug or dim
45
+ define_method("#{distance}!") { find_by_distance(i + 1, false) }
46
+ end
47
+
48
+ instance_eval { alias [] new }
49
+
50
+ def relative_intervals
62
51
  intervals_semitones[1..-1].each_with_index.map do |n, i|
63
52
  if i.zero?
64
53
  n
@@ -72,8 +61,20 @@ module Coltrane
72
61
  intervals.map(&:name)
73
62
  end
74
63
 
75
- def has?(interval_name)
76
- @intervals.include?(IntervalClass[interval_name])
64
+ def find(interval)
65
+ interval.clone if detect { |i| interval == i }
66
+ end
67
+
68
+ def has?(interval)
69
+ !!find(interval)
70
+ end
71
+
72
+ def find_by_distance(n, accept_altered = true)
73
+ strategy = (accept_altered ? :as : :as!)
74
+ map { |interval| interval.send(strategy, n) }
75
+ .compact
76
+ .sort_by { |i| i.alteration.abs }
77
+ .first
77
78
  end
78
79
 
79
80
  alias interval_names names
@@ -87,7 +88,7 @@ module Coltrane
87
88
  end
88
89
 
89
90
  def shift(ammount)
90
- IntervalSequence.new(intervals: intervals.map do |i|
91
+ self.class.new(*intervals.map do |i|
91
92
  (i.semitones + ammount) % 12
92
93
  end)
93
94
  end
@@ -97,7 +98,7 @@ module Coltrane
97
98
  end
98
99
 
99
100
  def inversion(index)
100
- IntervalSequence.new(intervals: intervals.rotate(index)).zero_it
101
+ self.class.new(*intervals.rotate(index)).zero_it
101
102
  end
102
103
 
103
104
  def next_inversion
@@ -109,9 +110,7 @@ module Coltrane
109
110
  end
110
111
 
111
112
  def inversions
112
- Array.new(intervals.length) do |index|
113
- inversion(index)
114
- end
113
+ Array.new(intervals.length) { |i| inversion(i) }
115
114
  end
116
115
 
117
116
  def intervals_semitones
@@ -143,14 +142,14 @@ module Coltrane
143
142
 
144
143
  private
145
144
 
146
- def intervals_from_distances(distances)
147
- distances[0..-2].reduce([IntervalClass[0]]) do |memo, d|
145
+ def intervals_from_relative_intervals(relative_intervals)
146
+ relative_intervals[0..-2].reduce([Interval[0]]) do |memo, d|
148
147
  memo + [memo.last + d]
149
148
  end
150
149
  end
151
150
 
152
151
  def intervals_from_notes(notes)
153
- notes.map { |n| n - notes.root }.sort_by(&:semitones)
152
+ notes.map { |n| notes.root - n }.sort_by(&:semitones)
154
153
  end
155
154
  end
156
155
  end
data/lib/coltrane/key.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coltrane
2
4
  class Key < DiatonicScale
3
5
  KEY_REGEX = /([A-G][#b]?)([mM]?)/
@@ -11,4 +13,4 @@ module Coltrane
11
13
  new(notation)
12
14
  end
13
15
  end
14
- end
16
+ end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Coltrane
4
-
5
4
  # This module takes care of adding to progressions knowledge that is more
6
5
  # based on common standards and practices.
7
6
  module NotableProgressions
data/lib/coltrane/note.rb CHANGED
@@ -83,22 +83,16 @@ module Coltrane
83
83
  end
84
84
 
85
85
  def -(other)
86
- result = super(other)
87
- result.is_a?(Note) ? result.alter(alteration) : result
86
+ super(other).yield_self { |r| r.is_a?(Note) ? r.alter(alteration) : r }
88
87
  end
89
88
 
90
89
  def +(other)
91
- result = super(other)
92
- result.is_a?(Note) ? result.alter(alteration) : result
93
- end
94
-
95
- def interval_to(note_name)
96
- Note[note_name] - self
90
+ super(other).yield_self { |r| r.is_a?(Note) ? r.alter(alteration) : r }
97
91
  end
98
92
 
99
93
  def as(letter)
100
- a = (self - Note[letter])
101
- alter([a.semitones, -((-a).semitones)].min_by(&:abs))
94
+ a = (Note[letter] - self)
95
+ alter([a.semitones, -(-a).semitones].min_by(&:abs))
102
96
  end
103
97
  end
104
98
  end
@@ -75,11 +75,11 @@ module Coltrane
75
75
  end
76
76
 
77
77
  def alter(alteration)
78
- NoteSet[*map {|n| n.alter(alteration)}]
78
+ NoteSet[*map { |n| n.alter(alteration) }]
79
79
  end
80
80
 
81
81
  def alter_accidentals(alteration)
82
- NoteSet[*map {|n| n.alter(alteration) if n.accidental?}]
82
+ NoteSet[*map { |n| n.alter(alteration) if n.accidental? }]
83
83
  end
84
84
 
85
85
  def interval_sequence
@@ -16,11 +16,15 @@ module Coltrane
16
16
 
17
17
  NOTATION = %w[C C# D D# E F F# G G# A A# B].freeze
18
18
 
19
+ def self.all_letters
20
+ %w[C D E F G A B]
21
+ end
22
+
19
23
  def self.all
20
24
  NOTATION.map { |n| new(n) }
21
25
  end
22
26
 
23
- def initialize(arg=nil, frequency: nil)
27
+ def initialize(arg = nil, frequency: nil)
24
28
  @integer = case arg
25
29
  when String then NOTATION.index(arg)
26
30
  when Frequency then frequency_to_integer(Frequency.new(arg))
@@ -46,6 +50,24 @@ module Coltrane
46
50
  NOTATION[integer]
47
51
  end
48
52
 
53
+ def letter
54
+ name[0]
55
+ end
56
+
57
+ def ascending_interval_to(other)
58
+ Interval.new(self, (other.is_a?(PitchClass) ? other : Note.new(other)))
59
+ end
60
+
61
+ alias interval_to ascending_interval_to
62
+
63
+ def descending_interval_to(other)
64
+ Interval.new(
65
+ self,
66
+ (other.is_a?(PitchClass) ? other : Note.new(other)),
67
+ ascending: false
68
+ )
69
+ end
70
+
49
71
  alias name true_notation
50
72
 
51
73
  def pretty_name
@@ -80,7 +102,7 @@ module Coltrane
80
102
  case other
81
103
  when Interval then self.class[integer - other.semitones]
82
104
  when Integer then self.class[integer - other]
83
- when PitchClass then IntervalClass[frequency / other.frequency]
105
+ when PitchClass then Interval.new(self, other)
84
106
  when Frequency then self.class.new(frequency: frequency - other)
85
107
  end
86
108
  end
@@ -1,251 +1,253 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Qualities
2
4
  QUALITIES = {
3
- "Perfect Unison" => {
4
- "Minor Third" => {
5
- "Diminished Fifth" => {
6
- "name" => "dim",
7
- "Diminished Seventh" => {
8
- "name" => "dim7",
9
- "Minor Ninth" => {
10
- "name" => "dim9"
5
+ 'Perfect Unison' => {
6
+ 'Minor Third' => {
7
+ 'Diminished Fifth' => {
8
+ 'name' => 'dim',
9
+ 'Diminished Seventh' => {
10
+ 'name' => 'dim7',
11
+ 'Minor Ninth' => {
12
+ 'name' => 'dim9'
11
13
  },
12
- "Major Ninth" => {
13
- "name" => "dim(b9)"
14
+ 'Major Ninth' => {
15
+ 'name' => 'dim(b9)'
14
16
  }
15
17
  },
16
- "Minor Seventh" => {
17
- "name" => "m7b5",
18
- "Minor Ninth" => {
19
- "name" => "m7b5b9",
20
- "Perfect Eleventh" => {
21
- "name" => "m7b5b11",
22
- "Major Thirteenth" => {
23
- "name" => "m7b5b13"
18
+ 'Minor Seventh' => {
19
+ 'name' => 'm7b5',
20
+ 'Minor Ninth' => {
21
+ 'name' => 'm7b5b9',
22
+ 'Perfect Eleventh' => {
23
+ 'name' => 'm7b5b11',
24
+ 'Major Thirteenth' => {
25
+ 'name' => 'm7b5b13'
24
26
  }
25
27
  }
26
28
  },
27
- "Major Ninth" => {
28
- "name" => "m7b5(9)"
29
+ 'Major Ninth' => {
30
+ 'name' => 'm7b5(9)'
29
31
  }
30
32
  }
31
33
  },
32
- "Perfect Fifth" => {
33
- "name" => "m",
34
- "Major Sixth" => {
35
- "name" => "m6"
34
+ 'Perfect Fifth' => {
35
+ 'name' => 'm',
36
+ 'Major Sixth' => {
37
+ 'name' => 'm6'
36
38
  },
37
- "Minor Seventh" => {
38
- "name" => "m7",
39
- "Minor Ninth" => {
40
- "name" => "m9",
41
- "Perfect Eleventh" => {
42
- "name" => "m11"
39
+ 'Minor Seventh' => {
40
+ 'name' => 'm7',
41
+ 'Minor Ninth' => {
42
+ 'name' => 'm9',
43
+ 'Perfect Eleventh' => {
44
+ 'name' => 'm11'
43
45
  }
44
46
  }
45
47
  },
46
- "Major Seventh" => {
47
- "name" => "m(M7)",
48
- "Major Ninth" => {
49
- "name" => "m(M9)",
50
- "Perfect Eleventh" => {
51
- "name" => "m(M11)",
52
- "Major Thirteenth" => {
53
- "name" => "m(M13)"
48
+ 'Major Seventh' => {
49
+ 'name' => 'm(M7)',
50
+ 'Major Ninth' => {
51
+ 'name' => 'm(M9)',
52
+ 'Perfect Eleventh' => {
53
+ 'name' => 'm(M11)',
54
+ 'Major Thirteenth' => {
55
+ 'name' => 'm(M13)'
54
56
  }
55
57
  }
56
58
  }
57
59
  }
58
60
  }
59
61
  },
60
- "Major Third" => {
61
- "Perfect Fifth" => {
62
- "name" => "M",
63
- "Major Sixth" => {
64
- "name" => "M6",
65
- "Major Ninth" => {
66
- "name" => "6/9",
67
- "Perfect Eleventh" => {
68
- "name" => "6/9(add11)"
62
+ 'Major Third' => {
63
+ 'Perfect Fifth' => {
64
+ 'name' => 'M',
65
+ 'Major Sixth' => {
66
+ 'name' => 'M6',
67
+ 'Major Ninth' => {
68
+ 'name' => '6/9',
69
+ 'Perfect Eleventh' => {
70
+ 'name' => '6/9(add11)'
69
71
  }
70
72
  }
71
73
  },
72
- "Minor Seventh" => {
73
- "name" => "7",
74
- "Major Ninth" => {
75
- "name" => "9",
76
- "Perfect Eleventh" => {
77
- "name" => "11",
78
- "Major Thirteenth" => {
79
- "name" => "13"
74
+ 'Minor Seventh' => {
75
+ 'name' => '7',
76
+ 'Major Ninth' => {
77
+ 'name' => '9',
78
+ 'Perfect Eleventh' => {
79
+ 'name' => '11',
80
+ 'Major Thirteenth' => {
81
+ 'name' => '13'
80
82
  }
81
83
  }
82
84
  }
83
85
  },
84
- "Major Seventh" => {
85
- "name" => "M7",
86
- "Major Ninth" => {
87
- "name" => "M9",
88
- "Perfect Eleventh" => {
89
- "name" => "M11",
90
- "Major Thirteenth" => {
91
- "name" => "M13"
86
+ 'Major Seventh' => {
87
+ 'name' => 'M7',
88
+ 'Major Ninth' => {
89
+ 'name' => 'M9',
90
+ 'Perfect Eleventh' => {
91
+ 'name' => 'M11',
92
+ 'Major Thirteenth' => {
93
+ 'name' => 'M13'
92
94
  }
93
95
  }
94
96
  }
95
97
  }
96
98
  },
97
- "Augmented Fifth" => {
98
- "name" => "+",
99
- "Minor Seventh" => {
100
- "name" => "+7",
101
- "Major Ninth" => {
102
- "name" => "+9",
103
- "Perfect Eleventh" => {
104
- "name" => "+11",
105
- "Major Thirteenth" => {
106
- "name" => "+13"
99
+ 'Augmented Fifth' => {
100
+ 'name' => '+',
101
+ 'Minor Seventh' => {
102
+ 'name' => '+7',
103
+ 'Major Ninth' => {
104
+ 'name' => '+9',
105
+ 'Perfect Eleventh' => {
106
+ 'name' => '+11',
107
+ 'Major Thirteenth' => {
108
+ 'name' => '+13'
107
109
  }
108
110
  }
109
111
  }
110
112
  },
111
- "Major Seventh" => {
112
- "name" => "+M7",
113
- "Major Ninth" => {
114
- "name" => "+M9",
115
- "Perfect Eleventh" => {
116
- "name" => "+M11",
117
- "Major Thirteenth" => {
118
- "name" => "+M13"
113
+ 'Major Seventh' => {
114
+ 'name' => '+M7',
115
+ 'Major Ninth' => {
116
+ 'name' => '+M9',
117
+ 'Perfect Eleventh' => {
118
+ 'name' => '+M11',
119
+ 'Major Thirteenth' => {
120
+ 'name' => '+M13'
119
121
  }
120
122
  }
121
123
  }
122
124
  }
123
125
  }
124
126
  },
125
- "Major Second" => {
126
- "Perfect Fifth" => {
127
- "name" => "Msus2",
128
- "Major Sixth" => {
129
- "name" => "M6sus2",
130
- "Major Ninth" => {
131
- "name" => "6/9sus2",
132
- "Perfect Eleventh" => {
133
- "name" => "6/9(add11)sus2"
127
+ 'Major Second' => {
128
+ 'Perfect Fifth' => {
129
+ 'name' => 'Msus2',
130
+ 'Major Sixth' => {
131
+ 'name' => 'M6sus2',
132
+ 'Major Ninth' => {
133
+ 'name' => '6/9sus2',
134
+ 'Perfect Eleventh' => {
135
+ 'name' => '6/9(add11)sus2'
134
136
  }
135
137
  }
136
138
  },
137
- "Minor Seventh" => {
138
- "name" => "7sus2",
139
- "Major Ninth" => {
140
- "name" => "9sus2",
141
- "Perfect Eleventh" => {
142
- "name" => "11sus2",
143
- "Major Thirteenth" => {
144
- "name" => "13sus2"
139
+ 'Minor Seventh' => {
140
+ 'name' => '7sus2',
141
+ 'Major Ninth' => {
142
+ 'name' => '9sus2',
143
+ 'Perfect Eleventh' => {
144
+ 'name' => '11sus2',
145
+ 'Major Thirteenth' => {
146
+ 'name' => '13sus2'
145
147
  }
146
148
  }
147
149
  }
148
150
  },
149
- "Major Seventh" => {
150
- "name" => "M7sus2",
151
- "Major Ninth" => {
152
- "name" => "M9sus2",
153
- "Perfect Eleventh" => {
154
- "name" => "M11sus2",
155
- "Major Thirteenth" => {
156
- "name" => "M13sus2"
151
+ 'Major Seventh' => {
152
+ 'name' => 'M7sus2',
153
+ 'Major Ninth' => {
154
+ 'name' => 'M9sus2',
155
+ 'Perfect Eleventh' => {
156
+ 'name' => 'M11sus2',
157
+ 'Major Thirteenth' => {
158
+ 'name' => 'M13sus2'
157
159
  }
158
160
  }
159
161
  }
160
162
  }
161
163
  },
162
- "Augmented Fifth" => {
163
- "name" => "+sus2",
164
- "Minor Seventh" => {
165
- "name" => "+7sus2",
166
- "Major Ninth" => {
167
- "name" => "+9sus2",
168
- "Perfect Eleventh" => {
169
- "name" => "+11sus2",
170
- "Major Thirteenth" => {
171
- "name" => "+13sus2"
164
+ 'Augmented Fifth' => {
165
+ 'name' => '+sus2',
166
+ 'Minor Seventh' => {
167
+ 'name' => '+7sus2',
168
+ 'Major Ninth' => {
169
+ 'name' => '+9sus2',
170
+ 'Perfect Eleventh' => {
171
+ 'name' => '+11sus2',
172
+ 'Major Thirteenth' => {
173
+ 'name' => '+13sus2'
172
174
  }
173
175
  }
174
176
  }
175
177
  },
176
- "Major Seventh" => {
177
- "name" => "+M7sus2",
178
- "Major Ninth" => {
179
- "name" => "+M9sus2",
180
- "Perfect Eleventh" => {
181
- "name" => "+M11sus2",
182
- "Major Thirteenth" => {
183
- "name" => "+M13sus2"
178
+ 'Major Seventh' => {
179
+ 'name' => '+M7sus2',
180
+ 'Major Ninth' => {
181
+ 'name' => '+M9sus2',
182
+ 'Perfect Eleventh' => {
183
+ 'name' => '+M11sus2',
184
+ 'Major Thirteenth' => {
185
+ 'name' => '+M13sus2'
184
186
  }
185
187
  }
186
188
  }
187
189
  }
188
190
  }
189
191
  },
190
- "Perfect Fourth" => {
191
- "Perfect Fifth" => {
192
- "name" => "Msus4",
193
- "Major Sixth" => {
194
- "name" => "M6sus4",
195
- "Major Ninth" => {
196
- "name" => "6/9sus4",
197
- "Perfect Eleventh" => {
198
- "name" => "6/9(add11)sus4"
192
+ 'Perfect Fourth' => {
193
+ 'Perfect Fifth' => {
194
+ 'name' => 'Msus4',
195
+ 'Major Sixth' => {
196
+ 'name' => 'M6sus4',
197
+ 'Major Ninth' => {
198
+ 'name' => '6/9sus4',
199
+ 'Perfect Eleventh' => {
200
+ 'name' => '6/9(add11)sus4'
199
201
  }
200
202
  }
201
203
  },
202
- "Minor Seventh" => {
203
- "name" => "7sus4",
204
- "Major Ninth" => {
205
- "name" => "9sus4",
206
- "Perfect Eleventh" => {
207
- "name" => "11sus4",
208
- "Major Thirteenth" => {
209
- "name" => "13sus4"
204
+ 'Minor Seventh' => {
205
+ 'name' => '7sus4',
206
+ 'Major Ninth' => {
207
+ 'name' => '9sus4',
208
+ 'Perfect Eleventh' => {
209
+ 'name' => '11sus4',
210
+ 'Major Thirteenth' => {
211
+ 'name' => '13sus4'
210
212
  }
211
213
  }
212
214
  }
213
215
  },
214
- "Major Seventh" => {
215
- "name" => "M7sus4",
216
- "Major Ninth" => {
217
- "name" => "M9sus4",
218
- "Perfect Eleventh" => {
219
- "name" => "M11sus4",
220
- "Major Thirteenth" => {
221
- "name" => "M13sus4"
216
+ 'Major Seventh' => {
217
+ 'name' => 'M7sus4',
218
+ 'Major Ninth' => {
219
+ 'name' => 'M9sus4',
220
+ 'Perfect Eleventh' => {
221
+ 'name' => 'M11sus4',
222
+ 'Major Thirteenth' => {
223
+ 'name' => 'M13sus4'
222
224
  }
223
225
  }
224
226
  }
225
227
  }
226
228
  },
227
- "Augmented Fifth" => {
228
- "name" => "+sus4",
229
- "Minor Seventh" => {
230
- "name" => "+7sus4",
231
- "Major Ninth" => {
232
- "name" => "+9sus4",
233
- "Perfect Eleventh" => {
234
- "name" => "+11sus4",
235
- "Major Thirteenth" => {
236
- "name" => "+13sus4"
229
+ 'Augmented Fifth' => {
230
+ 'name' => '+sus4',
231
+ 'Minor Seventh' => {
232
+ 'name' => '+7sus4',
233
+ 'Major Ninth' => {
234
+ 'name' => '+9sus4',
235
+ 'Perfect Eleventh' => {
236
+ 'name' => '+11sus4',
237
+ 'Major Thirteenth' => {
238
+ 'name' => '+13sus4'
237
239
  }
238
240
  }
239
241
  }
240
242
  },
241
- "Major Seventh" => {
242
- "name" => "+M7sus4",
243
- "Major Ninth" => {
244
- "name" => "+M9sus4",
245
- "Perfect Eleventh" => {
246
- "name" => "+M11sus4",
247
- "Major Thirteenth" => {
248
- "name" => "+M13sus4"
243
+ 'Major Seventh' => {
244
+ 'name' => '+M7sus4',
245
+ 'Major Ninth' => {
246
+ 'name' => '+M9sus4',
247
+ 'Perfect Eleventh' => {
248
+ 'name' => '+M11sus4',
249
+ 'Major Thirteenth' => {
250
+ 'name' => '+M13sus4'
249
251
  }
250
252
  }
251
253
  }
@@ -253,5 +255,5 @@ module Qualities
253
255
  }
254
256
  }
255
257
  }
256
- }
257
- end
258
+ }.freeze
259
+ end