Class: Cooltrainer::Compound

Inherits:
Struct
  • Object
show all
Defined in:
lib/distorted/element_of_media/compound.rb

Overview

Struct to wrap a MediaMolecule option/attribute datum.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(isotopes, molecule: nil, valid: nil, default: nil, blurb: nil) ⇒ Compound

Massage the data then call ‘super` to set the members/values and create the accessors.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/distorted/element_of_media/compound.rb', line 33

def initialize(isotopes, molecule: nil, valid: nil, default: nil, blurb: nil)
  super(
    # The first argument defines the aliases for a single option and may be just a Symbol
    # or may be an Enumerable[Symbol] in which case all items after the first are aliases for the first.
    isotopes: isotopes.is_a?(Enumerable) ? isotopes.to_a : Array[isotopes],
    # Hint the MediaMolecule that should execute this Change.
    molecule: molecule,
    # Valid values for this option may be expressed as a Class a value must be an instance of,
    # a Regexp a String value must match, an Enumerable that a valid value must be in,
    # a Range a Float/Integer must be within, a special Boolean Set, etc etc.
    valid: case valid
      when Set then valid.to_a
      else valid
    end,
    # Optional default value to use when unset.
    default: default,
    # String description of this option's effect.
    blurb: blurb,
  )
end

Instance Attribute Details

#blurbObject

Returns the value of attribute blurb

Returns:

  • (Object)

    the current value of blurb



30
31
32
# File 'lib/distorted/element_of_media/compound.rb', line 30

def blurb
  @blurb
end

#defaultObject

Returns the value of attribute default

Returns:

  • (Object)

    the current value of default



30
31
32
# File 'lib/distorted/element_of_media/compound.rb', line 30

def default
  @default
end

#isotopesObject

Returns the value of attribute isotopes

Returns:

  • (Object)

    the current value of isotopes



30
31
32
# File 'lib/distorted/element_of_media/compound.rb', line 30

def isotopes
  @isotopes
end

#moleculeObject

Returns the value of attribute molecule

Returns:

  • (Object)

    the current value of molecule



30
31
32
# File 'lib/distorted/element_of_media/compound.rb', line 30

def molecule
  @molecule
end

#validObject

Returns the value of attribute valid

Returns:

  • (Object)

    the current value of valid



30
31
32
# File 'lib/distorted/element_of_media/compound.rb', line 30

def valid
  @valid
end

Instance Method Details

#elementObject

The first isotope is the “”“real”“” option name. Any others are aliases for it.



55
# File 'lib/distorted/element_of_media/compound.rb', line 55

def element; self.isotopes&.first; end

#inspectObject

Returns a longform String representation of one option.



59
60
61
62
# File 'lib/distorted/element_of_media/compound.rb', line 59

def inspect
  # Intentionally not including the blurb here since they are pretty long and messy.
  "#{self.isotopes.length > 1 ? self.isotopes : self.element}: #{"#{self.valid} " if self.valid}#{"(#{self.default})" if self.default}"
end

#to_optionsObject

Returns an Array of properly-formatted OptionParser::Switch strings for this Compound.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/distorted/element_of_media/compound.rb', line 65

def to_options
  # @isotopes is a Hash[Symbol] => Compound, allowing for Compound aliasing
  # to multiple Hash keys, e.g. libvips' `:Q` and `:quality` are two Hash keys
  # referencing the same Compound object.
  self.isotopes.each_with_object(Array[]) { |aka, commands|
    # Every Switch has at least one leading dash, and longer ones have two,
    # e.g. `-Q` vs `--quality`.
    command = "-"
    if aka.length > 1
      command << '-'.freeze
    end

    # Compounds that take a boolean should format their Switch string
    # as `--[no]-whatever` (including the brackets!) instead of taking
    # any kind of boolean-ish argument like true/false/yes/no.
    #
    # TODO: There seems to be a bug with Ruby optparse and multiple of these
    # "--[no]-whatever"-style Switches where only the final Switch will display,
    # so disable this for now in favor of separate --whatever/--no-whatever.
    # I have a very basic standalone repro case that fails, so it's not just DD.
    #
    #if @valid == BOOLEAN_VALUES or @valid == BOOLEAN_VALUES.to_a
    #  command << '[no]-'.freeze
    #end

    # Add the alias to form the command.
    command << aka.to_s

    # Format the valid values and/or default value and stick it on the end.
    # https://ruby-doc.org/stdlib/libdoc/optparse/rdoc/OptionParser.html#class-OptionParser-label-Type+Coercion
    if self.valid.is_a?(Range)
      command << " [#{self.valid.to_s}]"
    elsif self.valid == BOOLEAN_VALUES or self.valid == BOOLEAN_VALUES.to_a
      # Intentional no-op
    elsif self.valid.is_a?(Enumerable)
      command << " [#{self.valid.join(', '.freeze)}]"
    elsif not default.nil?
      command << " [#{self.default}]"
    else
      command << " [#{self.element.upcase}]"
    end

    commands << command

    # HACK around issue with multiple "--[no]-whatever"-style long arguments.
    # See above note and the commented-out implementation I'd like to use
    # instead of this. Remove this iff I can figure out what's wrong there.
    if self.valid == BOOLEAN_VALUES or self.valid == BOOLEAN_VALUES.to_a
      commands << "--no-#{aka}"
    end
  }
end

#to_sObject



56
# File 'lib/distorted/element_of_media/compound.rb', line 56

def to_s; self.element.to_s; end