Result API Reference¶
The Result class is an immutable value object that represents the outcome of a step in a SimpleFlow pipeline. It encapsulates the operation's value, contextual data, and any errors that occurred.
Class: SimpleFlow::Result¶
Location: /Users/dewayne/sandbox/git_repos/madbomber/simple_flow/lib/simple_flow/result.rb
Constructor¶
new(value, context: {}, errors: {})¶
Creates a new Result instance.
Parameters:
- value (Object) - The outcome of the operation
- context (Hash, optional) - Contextual data related to the operation (default: {})
- errors (Hash, optional) - Errors organized by category (default: {})
Returns: Result instance
Example:
# Basic result
result = SimpleFlow::Result.new(42)
# Result with context
result = SimpleFlow::Result.new(
{ user_id: 123 },
context: { timestamp: Time.now }
)
# Result with errors
result = SimpleFlow::Result.new(
nil,
errors: { validation: ["Email is required"] }
)
Instance Attributes¶
value¶
The outcome of the operation.
Type: Object (read-only)
Example:
context¶
Contextual data related to the operation.
Type: Hash (read-only)
Example:
errors¶
Errors that occurred during the operation, organized by category.
Type: Hash (read-only)
Example:
result = SimpleFlow::Result.new(nil, errors: {
validation: ["Email required", "Password too short"],
auth: ["Invalid credentials"]
})
result.errors[:validation] # => ["Email required", "Password too short"]
result.errors[:auth] # => ["Invalid credentials"]
Instance Methods¶
with_context(key, value)¶
Adds or updates context to the result. Returns a new Result instance with updated context.
Parameters:
- key (Symbol) - The key to store the context under
- value (Object) - The value to store
Returns: New Result instance
Immutability: This method creates a new Result object; the original is unchanged.
Example:
result = SimpleFlow::Result.new(42)
.with_context(:user_id, 123)
.with_context(:timestamp, Time.now)
result.context # => { user_id: 123, timestamp: 2025-11-15 12:00:00 }
Chaining:
result = SimpleFlow::Result.new(data)
.with_context(:step_name, "process_data")
.with_context(:duration, 0.5)
.with_context(:source, :api)
with_error(key, message)¶
Adds an error message under a specific key. If the key already exists, the message is appended to existing errors. Returns a new Result instance with updated errors.
Parameters:
- key (Symbol) - The category under which to store the error
- message (String) - The error message
Returns: New Result instance
Immutability: Creates a new Result object.
Example:
result = SimpleFlow::Result.new(nil)
.with_error(:validation, "Email is required")
.with_error(:validation, "Password too short")
.with_error(:auth, "Invalid credentials")
result.errors
# => {
# validation: ["Email is required", "Password too short"],
# auth: ["Invalid credentials"]
# }
Error Accumulation:
result = SimpleFlow::Result.new(data)
# Add first validation error
result = result.with_error(:validation, "Name is required")
# Add second validation error (accumulates)
result = result.with_error(:validation, "Email is required")
result.errors[:validation]
# => ["Name is required", "Email is required"]
halt(new_value = nil)¶
Halts the pipeline flow. Optionally updates the result's value. Returns a new Result instance with continue set to false.
Parameters:
- new_value (Object, optional) - New value to set (default: keep current value)
Returns: New Result instance with @continue = false
Example:
# Halt without changing value
result = SimpleFlow::Result.new(42).halt
result.continue? # => false
result.value # => 42
# Halt with new value
result = SimpleFlow::Result.new(42).halt(100)
result.continue? # => false
result.value # => 100
# Halt with error
result = SimpleFlow::Result.new(data)
.halt
.with_error(:validation, "Invalid input")
result.continue? # => false
result.errors # => { validation: ["Invalid input"] }
Usage in Steps:
step ->(result) {
if invalid?(result.value)
result.halt.with_error(:validation, "Invalid data")
else
result.continue(process(result.value))
end
}
continue(new_value)¶
Continues the pipeline flow with an updated value. Returns a new Result instance with the new value.
Parameters:
- new_value (Object) - The new value to set
Returns: New Result instance with updated value
Example:
Usage in Steps:
continue?¶
Checks if the pipeline should continue executing.
Returns: Boolean
- true if the pipeline should continue
- false if the pipeline has been halted
Example:
result = SimpleFlow::Result.new(42)
result.continue? # => true
result = result.halt
result.continue? # => false
Usage:
result = pipeline.call(initial_data)
if result.continue?
puts "Success: #{result.value}"
process_result(result)
else
puts "Failed: #{result.errors}"
handle_errors(result)
end
Usage Patterns¶
Basic Flow Control¶
step ->(result) {
if valid?(result.value)
result.continue(result.value)
else
result.halt.with_error(:validation, "Invalid")
end
}
Error Accumulation¶
step ->(result) {
result_obj = result
if invalid_email?(result.value[:email])
result_obj = result_obj.with_error(:email, "Invalid format")
end
if invalid_phone?(result.value[:phone])
result_obj = result_obj.with_error(:phone, "Invalid format")
end
# Continue even with errors (check later)
result_obj.continue(result.value)
}
step ->(result) {
if result.errors.any?
result.halt(result.value)
else
result.continue(result.value)
end
}
Context Propagation¶
pipeline = SimpleFlow::Pipeline.new do
step ->(result) {
result
.with_context(:started_at, Time.now)
.with_context(:user_id, 123)
.continue(result.value)
}
step ->(result) {
# Access context from previous step
user_id = result.context[:user_id]
data = fetch_user_data(user_id)
result
.with_context(:user_data, data)
.continue(result.value)
}
step ->(result) {
# All context available
duration = Time.now - result.context[:started_at]
result
.with_context(:duration, duration)
.continue(process(result.value))
}
end
Combining Operations¶
step ->(result) {
result
.with_context(:timestamp, Time.now)
.with_context(:source, :api)
.with_error(:warning, "Deprecated API version")
.continue(transformed_data)
}
Implementation Details¶
Immutability¶
All Result methods return new instances:
original = SimpleFlow::Result.new(42)
modified = original.with_context(:key, "value")
original.context # => {}
modified.context # => { key: "value" }
# original and modified are different objects
original.object_id != modified.object_id # => true
Internal State¶
The Result class maintains internal state that is preserved across method calls:
result = SimpleFlow::Result.new(42)
.halt
.with_context(:key, "value")
# @continue flag is preserved
result.continue? # => false
result.context # => { key: "value" }
Thread Safety¶
Result objects are immutable and thread-safe. Multiple threads can safely read from the same Result instance.
Related Documentation¶
- Pipeline API - How pipelines use Result objects
- Error Handling Guide - Error handling patterns
- Validation Patterns - Validation strategies