Class: HeadMusic::Style::Guides::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/style/guides/base.rb

Overview

Base class for style guides. A guide analyzes a voice against its ruleset, producing one annotation per rule.

Direct Known Subclasses

SpeciesHarmony, SpeciesMelody

Class Method Summary collapse

Class Method Details

.analyze(voice) ⇒ Object



7
8
9
# File 'lib/head_music/style/guides/base.rb', line 7

def self.analyze(voice)
  ruleset.map { |rule| rule.new(voice) }
end

.categoryObject

An open enum owned by the gem: :melody or :harmony today, with room for :rhythm or :form later. Declared on the semantic marker base classes.



39
40
41
# File 'lib/head_music/style/guides/base.rb', line 39

def self.category
  nil
end

.display_nameObject



43
44
45
# File 'lib/head_music/style/guides/base.rb', line 43

def self.display_name
  HeadMusic::Style::Guide.display_name_for(key)
end

.keyObject



33
34
35
# File 'lib/head_music/style/guides/base.rb', line 33

def self.key
  HeadMusic::Utilities::Case.to_snake_case(name.split("::").last)
end

.rulesetObject

Indirection, not a constant read: guides whose ruleset varies by configuration override this with a keyword signature, so an unconfigured use raises instead of silently inheriting an ancestor’s RULESET.



14
15
16
# File 'lib/head_music/style/guides/base.rb', line 14

def self.ruleset
  self::RULESET
end

.with(**options) ⇒ Object

Pairs this guide with configuration: ContourMelody.with(contour: :arch).

A guide gains configuration by declaring keywords on .ruleset, so a ruleset taking none accepts none. Saying that here, at configuration time, is the same choice ContourMelody makes in normalizing its contour in .with: the alternative is Ruby’s bare “wrong number of arguments (given 1, expected 0)” at the first analyze, mid-grading, naming neither the guide nor the option.



25
26
27
28
29
30
31
# File 'lib/head_music/style/guides/base.rb', line 25

def self.with(**options)
  if options.any? && method(:ruleset).parameters.empty?
    raise ArgumentError, "#{name} takes no configuration, so it cannot be given: #{options.keys.join(", ")}"
  end

  HeadMusic::Style::Guides::Configured.new(self, options)
end