coltrane 2.1.5 → 2.2.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.
@@ -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