Class: Operandi::Collection::Base

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/operandi/collection.rb

Overview

Storage for service arguments or outputs with type validation.

Examples:

Accessing values

service.arg[:name]     # => "John"
service.output[:user]  # => #<User id: 1>

Instance Method Summary collapse

Constructor Details

#initialize(instance, collection_type, storage = {}) ⇒ Base

Initialize a new collection.

Parameters:

  • instance (Base)

    the service instance

  • collection_type (String)

    "arguments" or "outputs"

  • storage (Hash) (defaults to: {})

    initial values

Raises:



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/operandi/collection.rb', line 32

def initialize(instance, collection_type, storage = {})
  validate_collection_type!(collection_type)

  @instance = instance
  @collection_type = collection_type
  @storage = storage

  return if storage.is_a?(Hash)

  message = "#{instance.class} - #{collection_type} must be a Hash"
  raise Operandi::ArgTypeError.new(message, service_class: instance.class)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args) ⇒ Object?

Access a value using method call syntax.

Parameters:

  • method_name (Symbol)

    the method name (used as key)

  • args (Array)

    method arguments (must be empty)

Returns:

  • (Object, nil)

    the stored value or nil

Raises:

  • (NoMethodError)

    if the key doesn't exist



133
134
135
136
137
# File 'lib/operandi/collection.rb', line 133

def method_missing(method_name, *args, &)
  return super unless respond_to_missing?(method_name, false)

  get(method_name)
end

Instance Method Details

#[](key) ⇒ Object?

Get a value using bracket notation.

Parameters:

  • key (Symbol)

    the key to retrieve

Returns:

  • (Object, nil)

    the stored value or nil



66
67
68
# File 'lib/operandi/collection.rb', line 66

def [](key)
  get(key)
end

#[]=(key, value) ⇒ Object

Set a value using bracket notation.

Parameters:

  • key (Symbol)

    the key to set

  • value (Object)

    the value to store

Returns:

  • (Object)

    the stored value



75
76
77
# File 'lib/operandi/collection.rb', line 75

def []=(key, value)
  set(key, value)
end

#extend_with_context(args) ⇒ Hash

Extend arguments hash with context values from this collection. Only applies to arguments collections.

Parameters:

  • args (Hash)

    arguments hash to extend

Returns:

  • (Hash)

    the extended arguments hash



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/operandi/collection.rb', line 115

def extend_with_context(args)
  return args unless @collection_type == CollectionTypes::ARGUMENTS

  settings_collection.each do |name, field|
    next if !field.context || args.key?(name) || !key?(name)

    args[field.name] = get(name)
  end

  args
end

#get(key) ⇒ Object?

Get a value from the collection.

Parameters:

  • key (Symbol)

    the key to retrieve

Returns:

  • (Object, nil)

    the stored value or nil



58
59
60
# File 'lib/operandi/collection.rb', line 58

def get(key)
  @storage[key]
end

#key?(key) ⇒ Boolean

Check if a key exists in the collection.

Parameters:

  • key (Symbol)

    the key to check

Returns:

  • (Boolean)

    true if key exists



# File 'lib/operandi/collection.rb', line 16

#load_defaultsvoid

This method returns an undefined value.

Load default values for fields that haven't been set.



82
83
84
85
86
87
88
89
90
91
92
# File 'lib/operandi/collection.rb', line 82

def load_defaults
  settings_collection.each do |name, settings|
    next if !settings.default_exists || key?(name)

    if settings.default.is_a?(Proc)
      set(name, @instance.instance_exec(&settings.default))
    else
      set(name, Utils.deep_dup(settings.default))
    end
  end
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Check if a method name corresponds to a stored key.

Parameters:

  • method_name (Symbol)

    the method name to check

  • include_private (Boolean) (defaults to: false)

    whether to include private methods

Returns:

  • (Boolean)

    true if the key exists



144
145
146
# File 'lib/operandi/collection.rb', line 144

def respond_to_missing?(method_name, include_private = false)
  key?(method_name) || settings_collection.key?(method_name) || super
end

#set(key, value) ⇒ Object

Set a value in the collection.

Parameters:

  • key (Symbol)

    the key to set

  • value (Object)

    the value to store

Returns:

  • (Object)

    the stored value



50
51
52
# File 'lib/operandi/collection.rb', line 50

def set(key, value)
  @storage[key] = value
end

#to_hHash

Convert collection to a hash.

Returns:

  • (Hash)

    the stored values



24
# File 'lib/operandi/collection.rb', line 24

def_delegators :@storage, :key?, :to_h

#validate!void

This method returns an undefined value.

Validate all values against their type definitions.

Raises:



98
99
100
101
102
103
104
105
106
107
108
# File 'lib/operandi/collection.rb', line 98

def validate!
  settings_collection.each do |name, field|
    next if field.optional && (!key?(name) || get(name).nil?)

    # validate_type! returns the validated value
    validated_value = field.validate_type!(get(name))

    # Store the validated value back
    set(name, validated_value) if validated_value != get(name)
  end
end