class ProcessExecuter::Options::Base
Defines, validates, and holds a set of option values
Options are defined by subclasses by overriding the ‘define_options` method.
@example Define an options class with two options
class MyOptions < ProcessExecuter::Options::Base def define_options # Call super to include options defined in the parent class [ *super, ProcessExecuter::Options::OptionDefinition.new( :option1, default: '', validator: method(:assert_is_string) ), ProcessExecuter::Options::OptionDefinition.new( :option2, default: '', validator: method(:assert_is_string) ), ProcessExecuter::Options::OptionDefinition.new( :option3, default: '', validator: method(:assert_is_string) ) ] end def assert_is_string(key, value) return if value.is_a?(String) errors << "#{key} must be a String but was #{value}" end end options = MyOptions.new(option1: 'value1', option2: 'value2') options.option1 # => 'value1' options.option2 # => 'value2'
@example invalid option values
begin options = MyOptions.new(option1: 1, option2: 2) rescue ProcessExecuter::ArgumentError => e e.message #=> "option1 must be a String but was 1\noption2 must be a String but was 2" end
@api public
Attributes
The list of validation errors
Validators should add error messages to this array.
@return [Array<String>]
@api private
@!attribute [r]
A hash of all options keyed by the option name
@return [Hash<Object, Object>]
@api private
Public Class Methods
Source
# File lib/process_executer/options/base.rb, line 63 def initialize(**options_hash) @options_hash = allowed_options.transform_values(&:default).merge(options_hash) @errors = [] assert_no_unknown_options define_accessor_methods validate_options end
Create a new Options object
Normally you would use a subclass instead of instantiating this class directly.
@example
options = MyOptions.new(option1: 'value1', option2: 'value2')
@example with invalid option values
begin options = MyOptions.new(option1: 1, option2: 2) rescue ProcessExecuter::ArgumentError => e e.message #=> "option1 must be a String but was 1\noption2 must be a String but was 2" end
@param options_hash [Hash] a hash of options
Public Instance Methods
Source
# File lib/process_executer/options/base.rb, line 88 def allowed_options @allowed_options ||= define_options.to_h do |option| [option.name, option] end.freeze end
All the allowed options as a hash whose keys are the option names
The returned hash what is returned from ‘define_options` but with the option names as keys. The values are instances of `OptionDefinition`.
The returned hash is frozen and cannot be modified.
@example
options = MyOptions.new(option1: 'value1', option2: 'value2')
options.allowed_options # => {
option1: #<OptionDefinition>,
option2: #<OptionDefinition>
}
@return [Hash<Symbol, ProcessExecuter::Options::OptionDefinition>] A hash
where keys are option names and values are their definitions.
Source
# File lib/process_executer/options/base.rb, line 146 def each_with_object(obj, &) options_hash.each_with_object(obj, &) end
Iterate over each option with an object
@example
options = MyOptions.new(option1: 'value1', option2: 'value2') options.each_with_object({}) { |(option_key, option_value), obj| obj[option_key] = option_value } # => { option1: "value1", option2: "value2" }
@yield [key_value, obj]
@yieldparam key_value [Array<Object, Object>] An array containing the option key and its value
@yieldparam obj [Object] The object passed to the block.
@return [Object] the obj passed to the block
Source
# File lib/process_executer/options/base.rb, line 115 def inspect options_hash.inspect end
A string representation of the options
@example
options = MyOptions.new(option1: 'value1', option2: 'value2') options.inspect # => '{:option1=>"value1", :option2=>"value2"}'
@return [String]
Source
# File lib/process_executer/options/base.rb, line 213 def merge(*other_options_hashes) merged_options = other_options_hashes.reduce(options_hash, :merge) self.class.new(**merged_options) end
Returns a new options object formed by merging self with each of other_hashes
@example
options = MyOptions.new(option1: 'value1', option2: 'value2') options.object_id # => 1025 h1 = { option2: 'new_value2' } h2 = { option3: 'value3' } merged_options = options.merge(h1, h2) merged_options.object_id # => 1059
@param other_options_hashes [Array<Hash>] the options to merge into the current options
@return [self.class]
@raise [ProcessExecuter::ArgumentError] if the merged options contain an
unknown option or an invalid option value
Source
# File lib/process_executer/options/base.rb, line 183 def merge!(*other_options_hashes) original_options_hash = @options_hash @options_hash = original_options_hash.dup.merge!(*other_options_hashes) @errors = [] assert_no_unknown_options validate_options self rescue ProcessExecuter::ArgumentError @options_hash = original_options_hash @errors = [] raise end
Merge the given options into the current options object
Subsequent hashes’ values overwrite earlier ones for the same key.
The merged options are checked the same way the constructor checks its options: unknown options and invalid option values raise a ‘ProcessExecuter::ArgumentError`. In that case, the current options object is left unchanged.
@example
options = MyOptions.new(option1: 'value1', option2: 'value2') h1 = { option2: 'new_value2' } h2 = { option3: 'value3' } options.merge!(h1, h2) # => options with {option1: "value1", option2: "new_value2", option3: "value3"}
@example with an invalid option value
options = MyOptions.new(option1: 'value1') begin options.merge!(option1: 1) rescue ProcessExecuter::ArgumentError => e e.message #=> "option1 must be a String but was 1" options.option1 #=> 'value1' end
@param other_options_hashes [Array<Hash>] zero or more hashes to merge into the current options
@return [self] the current options object with the merged options
@raise [ProcessExecuter::ArgumentError] if the merged options contain an
unknown option or an invalid option value
@api public
Source
# File lib/process_executer/options/base.rb, line 127 def to_h options_hash.dup end
A hash representation of the options
@example
options = MyOptions.new(option1: 'value1', option2: 'value2') options.to_h # => { option1: "value1", option2: "value2" }
@return [Hash]
Source
# File lib/process_executer/options/base.rb, line 103 def to_s "#{super.to_s[0..-2]} #{inspect}>" end
A string representation of the object that includes the options
@example
options = MyOptions.new(option1: 'value1', option2: 'value2') options.to_s # => #<MyOptions option1: "value1", option2: "value2">'
@return [String]
Protected Instance Methods
Source
# File lib/process_executer/options/base.rb, line 228 def define_options [].freeze end
An array of OptionDefinition objects that define the allowed options
Subclasses MUST override this method to define the allowed options.
@return [Array<OptionDefinition>]
@api private
Source
# File lib/process_executer/options/base.rb, line 239 def valid_option?(option) allowed_options.keys.include?(option) end
Determine if the given option is a valid option
May be overridden by subclasses to add additional validation.
@param option [Symbol] the option to be tested @return [Boolean] true if the given option is a valid option @api private
Private Instance Methods
Source
# File lib/process_executer/options/base.rb, line 293 def assert_no_unknown_options unknown_options = options_hash.keys.reject { |key| valid_option?(key) } return if unknown_options.empty? raise( ArgumentError, "Unknown option#{'s' if unknown_options.count > 1}: #{unknown_options.join(', ')}" ) end
Determine if the options hash contains any unknown options @return [void] @raise [ProcessExecuter::ArgumentError] if the options hash contains any unknown options @api private
Source
# File lib/process_executer/options/base.rb, line 281 def define_accessor_methods allowed_options.each_key do |option| define_singleton_method(option) do options_hash[option] end end end
Define accessor methods for each option @return [void] @api private
Source
# File lib/process_executer/options/base.rb, line 269 def validate_options options_hash.each_key do |option_key| validator = allowed_options[option_key]&.validator instance_exec(option_key, send(option_key), &validator.to_proc) unless validator.nil? end raise ProcessExecuter::ArgumentError, errors.join("\n") unless errors.empty? end
Raise an argument error for invalid option values @return [void] @raise [ProcessExecuter::ArgumentError] if any invalid option values are found @api private